diff options
Diffstat (limited to 'include')
104 files changed, 14164 insertions, 104 deletions
diff --git a/include/base.h b/include/base.h index 594e5bfe4..ba8184c3c 100644 --- a/include/base.h +++ b/include/base.h @@ -1 +1,228 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __BASE_H__
#define __BASE_H__
#include "inspircd_config.h"
#include <time.h>
#include <map>
#include <deque>
#include <string>
/** Do we use this? -- Brain */
typedef void* VoidPointer;
/** A private data store for an Extensible class */
typedef std::map<std::string,char*> ExtensibleStore;
/** Needed */
class InspIRCd;
/** The base class for all inspircd classes.
* Wherever possible, all classes you create should inherit from this,
* giving them the ability to be passed to various core functions
* as 'anonymous' classes.
*/
class CoreExport classbase
{
public:
/** Time that the object was instantiated (used for TS calculation etc)
*/
time_t age;
/** Constructor.
* Sets the object's time
*/
classbase();
/** Destructor.
* Does sweet FA.
*/
~classbase() { }
};
/** class Extensible is the parent class of many classes such as userrec and chanrec.
* class Extensible implements a system which allows modules to 'extend' the class by attaching data within
* a map associated with the object. In this way modules can store their own custom information within user
* objects, channel objects and server objects, without breaking other modules (this is more sensible than using
* a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and
* supports arbitary data storage).
*/
class CoreExport Extensible : public classbase
{
/** Private data store.
* Holds all extensible metadata for the class.
*/
ExtensibleStore Extension_Items;
public:
/** Extend an Extensible class.
*
* @param key The key parameter is an arbitary string which identifies the extension data
* @param p This parameter is a pointer to any data you wish to associate with the object
*
* You must provide a key to store the data as via the parameter 'key' and store the data
* in the templated parameter 'p'.
* The data will be inserted into the map. If the data already exists, you may not insert it
* twice, Extensible::Extend will return false in this case.
*
* @return Returns true on success, false if otherwise
*/
template<typename T> bool Extend(const std::string &key, T* p)
{
/* This will only add an item if it doesnt already exist,
* the return value is a std::pair of an iterator to the
* element, and a bool saying if it was actually inserted.
*/
return this->Extension_Items.insert(std::make_pair(key, (char*)p)).second;
}
/** Extend an Extensible class.
*
* @param key The key parameter is an arbitary string which identifies the extension data
*
* You must provide a key to store the data as via the parameter 'key', this single-parameter
* version takes no 'data' parameter, this is used purely for boolean values.
* The key will be inserted into the map with a NULL 'data' pointer. If the key already exists
* then you may not insert it twice, Extensible::Extend will return false in this case.
*
* @return Returns true on success, false if otherwise
*/
bool Extend(const std::string &key)
{
/* This will only add an item if it doesnt already exist,
* the return value is a std::pair of an iterator to the
* element, and a bool saying if it was actually inserted.
*/
return this->Extension_Items.insert(std::make_pair(key, (char*)NULL)).second;
}
/** Shrink an Extensible class.
*
* @param key The key parameter is an arbitary string which identifies the extension data
*
* You must provide a key name. The given key name will be removed from the classes data. If
* you provide a nonexistent key (case is important) then the function will return false.
* @return Returns true on success.
*/
bool Shrink(const std::string &key);
/** Get an extension item.
*
* @param key The key parameter is an arbitary string which identifies the extension data
* @param p If you provide a non-existent key, this value will be NULL. Otherwise a pointer to the item you requested will be placed in this templated parameter.
* @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible.
*/
template<typename T> bool GetExt(const std::string &key, T* &p)
{
ExtensibleStore::iterator iter = this->Extension_Items.find(key); /* Find the item */
if(iter != this->Extension_Items.end())
{
p = (T*)iter->second; /* Item found */
return true;
}
else
{
p = NULL; /* Item not found */
return false;
}
}
/** Get an extension item.
*
* @param key The key parameter is an arbitary string which identifies the extension data
* @return Returns true if the item was found and false if it was not.
*
* This single-parameter version only checks if the key exists, it does nothing with
* the 'data' field and is probably only useful in conjunction with the single-parameter
* version of Extend().
*/
bool GetExt(const std::string &key)
{
return (this->Extension_Items.find(key) != this->Extension_Items.end());
}
/** Get a list of all extension items names.
* @param list A deque of strings to receive the list
* @return This function writes a list of all extension items stored in this object by name into the given deque and returns void.
*/
void GetExtList(std::deque<std::string> &list);
};
/** BoolSet is a utility class designed to hold eight bools in a bitmask.
* Use BoolSet::Set and BoolSet::Get to set and get bools in the bitmask,
* and Unset and Invert for special operations upon them.
*/
class CoreExport BoolSet : public classbase
{
/** Actual bit values */
char bits;
public:
/** The default constructor initializes the BoolSet to all values unset.
*/
BoolSet();
/** This constructor copies the default bitmask from a char
*/
BoolSet(char bitmask);
/** The Set method sets one bool in the set.
*
* @param number The number of the item to set. This must be between 0 and 7.
*/
void Set(int number);
/** The Get method returns the value of one bool in the set
*
* @param number The number of the item to retrieve. This must be between 0 and 7.
*
* @return True if the item is set, false if it is unset.
*/
bool Get(int number);
/** The Unset method unsets one value in the set
*
* @param number The number of the item to set. This must be between 0 and 7.
*/
void Unset(int number);
/** The Unset method inverts (flips) one value in the set
*
* @param number The number of the item to invert. This must be between 0 and 7.
*/
void Invert(int number);
/** Compare two BoolSets
*/
bool operator==(BoolSet other);
/** OR two BoolSets together
*/
BoolSet operator|(BoolSet other);
/** AND two BoolSets together
*/
BoolSet operator&(BoolSet other);
/** Assign one BoolSet to another
*/
bool operator=(BoolSet other);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __BASE_H__ +#define __BASE_H__ + +#include "inspircd_config.h" +#include <time.h> +#include <map> +#include <deque> +#include <string> + +/** Do we use this? -- Brain */ +typedef void* VoidPointer; + +/** A private data store for an Extensible class */ +typedef std::map<std::string,char*> ExtensibleStore; + +/** Needed */ +class InspIRCd; + +/** The base class for all inspircd classes. + * Wherever possible, all classes you create should inherit from this, + * giving them the ability to be passed to various core functions + * as 'anonymous' classes. +*/ +class CoreExport classbase +{ + public: + /** Time that the object was instantiated (used for TS calculation etc) + */ + time_t age; + + /** Constructor. + * Sets the object's time + */ + classbase(); + + /** Destructor. + * Does sweet FA. + */ + ~classbase() { } +}; + +/** class Extensible is the parent class of many classes such as userrec and chanrec. + * class Extensible implements a system which allows modules to 'extend' the class by attaching data within + * a map associated with the object. In this way modules can store their own custom information within user + * objects, channel objects and server objects, without breaking other modules (this is more sensible than using + * a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and + * supports arbitary data storage). + */ +class CoreExport Extensible : public classbase +{ + /** Private data store. + * Holds all extensible metadata for the class. + */ + ExtensibleStore Extension_Items; + +public: + + /** Extend an Extensible class. + * + * @param key The key parameter is an arbitary string which identifies the extension data + * @param p This parameter is a pointer to any data you wish to associate with the object + * + * You must provide a key to store the data as via the parameter 'key' and store the data + * in the templated parameter 'p'. + * The data will be inserted into the map. If the data already exists, you may not insert it + * twice, Extensible::Extend will return false in this case. + * + * @return Returns true on success, false if otherwise + */ + template<typename T> bool Extend(const std::string &key, T* p) + { + /* This will only add an item if it doesnt already exist, + * the return value is a std::pair of an iterator to the + * element, and a bool saying if it was actually inserted. + */ + return this->Extension_Items.insert(std::make_pair(key, (char*)p)).second; + } + + /** Extend an Extensible class. + * + * @param key The key parameter is an arbitary string which identifies the extension data + * + * You must provide a key to store the data as via the parameter 'key', this single-parameter + * version takes no 'data' parameter, this is used purely for boolean values. + * The key will be inserted into the map with a NULL 'data' pointer. If the key already exists + * then you may not insert it twice, Extensible::Extend will return false in this case. + * + * @return Returns true on success, false if otherwise + */ + bool Extend(const std::string &key) + { + /* This will only add an item if it doesnt already exist, + * the return value is a std::pair of an iterator to the + * element, and a bool saying if it was actually inserted. + */ + return this->Extension_Items.insert(std::make_pair(key, (char*)NULL)).second; + } + + /** Shrink an Extensible class. + * + * @param key The key parameter is an arbitary string which identifies the extension data + * + * You must provide a key name. The given key name will be removed from the classes data. If + * you provide a nonexistent key (case is important) then the function will return false. + * @return Returns true on success. + */ + bool Shrink(const std::string &key); + + /** Get an extension item. + * + * @param key The key parameter is an arbitary string which identifies the extension data + * @param p If you provide a non-existent key, this value will be NULL. Otherwise a pointer to the item you requested will be placed in this templated parameter. + * @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible. + */ + template<typename T> bool GetExt(const std::string &key, T* &p) + { + ExtensibleStore::iterator iter = this->Extension_Items.find(key); /* Find the item */ + if(iter != this->Extension_Items.end()) + { + p = (T*)iter->second; /* Item found */ + return true; + } + else + { + p = NULL; /* Item not found */ + return false; + } + } + + /** Get an extension item. + * + * @param key The key parameter is an arbitary string which identifies the extension data + * @return Returns true if the item was found and false if it was not. + * + * This single-parameter version only checks if the key exists, it does nothing with + * the 'data' field and is probably only useful in conjunction with the single-parameter + * version of Extend(). + */ + bool GetExt(const std::string &key) + { + return (this->Extension_Items.find(key) != this->Extension_Items.end()); + } + + /** Get a list of all extension items names. + * @param list A deque of strings to receive the list + * @return This function writes a list of all extension items stored in this object by name into the given deque and returns void. + */ + void GetExtList(std::deque<std::string> &list); +}; + +/** BoolSet is a utility class designed to hold eight bools in a bitmask. + * Use BoolSet::Set and BoolSet::Get to set and get bools in the bitmask, + * and Unset and Invert for special operations upon them. + */ +class CoreExport BoolSet : public classbase +{ + /** Actual bit values */ + char bits; + + public: + + /** The default constructor initializes the BoolSet to all values unset. + */ + BoolSet(); + + /** This constructor copies the default bitmask from a char + */ + BoolSet(char bitmask); + + /** The Set method sets one bool in the set. + * + * @param number The number of the item to set. This must be between 0 and 7. + */ + void Set(int number); + + /** The Get method returns the value of one bool in the set + * + * @param number The number of the item to retrieve. This must be between 0 and 7. + * + * @return True if the item is set, false if it is unset. + */ + bool Get(int number); + + /** The Unset method unsets one value in the set + * + * @param number The number of the item to set. This must be between 0 and 7. + */ + void Unset(int number); + + /** The Unset method inverts (flips) one value in the set + * + * @param number The number of the item to invert. This must be between 0 and 7. + */ + void Invert(int number); + + /** Compare two BoolSets + */ + bool operator==(BoolSet other); + + /** OR two BoolSets together + */ + BoolSet operator|(BoolSet other); + + /** AND two BoolSets together + */ + BoolSet operator&(BoolSet other); + + /** Assign one BoolSet to another + */ + bool operator=(BoolSet other); +}; + + +#endif + diff --git a/include/channels.h b/include/channels.h index ce7935c2d..b4fa1ca30 100644 --- a/include/channels.h +++ b/include/channels.h @@ -1 +1,551 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __CHANNELS_H__
#define __CHANNELS_H__
#include "inspircd_config.h"
#include "base.h"
#include <time.h>
#include <vector>
#include <string>
#include <map>
/** RFC1459 channel modes
*/
enum ChannelModes {
CM_TOPICLOCK = 't'-65, /* +t: Only operators can change topic */
CM_NOEXTERNAL = 'n'-65, /* +n: Only users in the channel can message it */
CM_INVITEONLY = 'i'-65, /* +i: Invite only */
CM_MODERATED = 'm'-65, /* +m: Only voices and above can talk */
CM_SECRET = 's'-65, /* +s: Secret channel */
CM_PRIVATE = 'p'-65, /* +p: Private channel */
CM_KEY = 'k'-65, /* +k: Keyed channel */
CM_LIMIT = 'l'-65 /* +l: Maximum user limit */
};
/* Forward declarations - needed */
class userrec;
class chanrec;
/** Holds an entry for a ban list, exemption list, or invite list.
* This class contains a single element in a channel list, such as a banlist.
*/
class HostItem : public classbase
{
public:
/** Time the item was added
*/
time_t set_time;
/** Who added the item
*/
char set_by[NICKMAX];
/** The actual item data
*/
char data[MAXBUF];
HostItem() { /* stub */ }
virtual ~HostItem() { /* stub */ }
};
/** A subclass of HostItem designed to hold channel bans (+b)
*/
class BanItem : public HostItem
{
};
/** Holds a complete ban list
*/
typedef std::vector<BanItem> BanList;
/** A list of users on a channel
*/
typedef std::map<userrec*,std::string> CUList;
/** Shorthand for CUList::iterator
*/
typedef CUList::iterator CUListIter;
/** Shorthand for CUList::const_iterator
*/
typedef CUList::const_iterator CUListConstIter;
/** A list of custom modes parameters on a channel
*/
typedef std::map<char,char*> CustomModeList;
/** used to hold a channel and a users modes on that channel, e.g. +v, +h, +o
*/
enum UserChannelModes {
UCMODE_OP = 1, /* Opped user */
UCMODE_VOICE = 2, /* Voiced user */
UCMODE_HOP = 4 /* Halfopped user */
};
/* Forward declaration -- required */
class InspIRCd;
/** A stored prefix and its rank
*/
typedef std::pair<char, unsigned int> prefixtype;
/** A list of prefixes set on a user in a channel
*/
typedef std::vector<prefixtype> pfxcontainer;
/** A list of users with zero or more prefixes set on them
*/
typedef std::map<userrec*, std::vector<prefixtype> > prefixlist;
/** Holds all relevent information for a channel.
* This class represents a channel, and contains its name, modes, time created, topic, topic set time,
* etc, and an instance of the BanList type.
*/
class CoreExport chanrec : public Extensible
{
private:
/** Pointer to creator object
*/
InspIRCd* ServerInstance;
/** Connect a chanrec to a userrec
*/
static chanrec* ForceChan(InspIRCd* Instance, chanrec* Ptr, userrec* user, const std::string &privs);
/** Set default modes for the channel on creation
*/
void SetDefaultModes();
/** A list of prefixes associated with each user in the channel
* (e.g. &%+ etc)
*/
prefixlist prefixes;
/** Maximum number of bans (cached)
*/
int maxbans;
public:
/** The channel's name.
*/
char name[CHANMAX];
/** Modes for the channel.
* This is not a null terminated string! It is a hash where
* each item in it represents if a mode is set. For example
* for mode +A, index 0. Use modechar-65 to calculate which
* field to check.
*/
char modes[64];
/** User lists.
* There are four user lists, one for
* all the users, one for the ops, one for
* the halfops and another for the voices.
*/
CUList internal_userlist;
/** Opped users.
* There are four user lists, one for
* all the users, one for the ops, one for
* the halfops and another for the voices.
*/
CUList internal_op_userlist;
/** Halfopped users.
* There are four user lists, one for
* all the users, one for the ops, one for
* the halfops and another for the voices.
*/
CUList internal_halfop_userlist;
/** Voiced users.
* There are four user lists, one for
* all the users, one for the ops, one for
* the halfops and another for the voices.
*/
CUList internal_voice_userlist;
/** Parameters for custom modes.
* One for each custom mode letter.
*/
CustomModeList custom_mode_params;
/** Channel topic.
* If this is an empty string, no channel topic is set.
*/
char topic[MAXTOPIC];
/** Creation time.
* This is a timestamp (TS) value.
*/
time_t created;
/** Time topic was set.
* If no topic was ever set, this will be equal to chanrec::created
*/
time_t topicset;
/** The last user to set the topic.
* If this member is an empty string, no topic was ever set.
*/
char setby[128];
/** Contains the channel user limit.
* If this value is zero, there is no limit in place.
*/
short int limit;
/** Contains the channel key.
* If this value is an empty string, there is no channel key in place.
*/
char key[32];
/** The list of all bans set on the channel.
*/
BanList bans;
/** Sets or unsets a custom mode in the channels info
* @param mode The mode character to set or unset
* @param mode_on True if you want to set the mode or false if you want to remove it
*/
void SetMode(char mode,bool mode_on);
/** Sets or unsets the parameters for a custom mode in a channels info
* @param mode The mode character to set or unset
* @param parameter The parameter string to associate with this mode character
* @param mode_on True if you want to set the mode or false if you want to remove it
*/
void SetModeParam(char mode,const char* parameter,bool mode_on);
/** Returns true if a mode is set on a channel
* @param mode The mode character you wish to query
* @return True if the custom mode is set, false if otherwise
*/
bool IsModeSet(char mode);
/** Returns the parameter for a custom mode on a channel.
* @param mode The mode character you wish to query
*
* For example if "+L #foo" is set, and you pass this method
* 'L', it will return '#foo'. If the mode is not set on the
* channel, or the mode has no parameters associated with it,
* it will return an empty string.
*
* @return The parameter for this mode is returned, or an empty string
*/
std::string GetModeParameter(char mode);
/** Obtain the channel "user counter"
* This returns the channel reference counter, which is initialized
* to 0 when the channel is created and incremented/decremented
* upon joins, parts quits and kicks.
*
* @return The number of users on this channel
*/
long GetUserCounter();
/** Add a user pointer to the internal reference list
* @param user The user to add
*
* The data inserted into the reference list is a table as it is
* an arbitary pointer compared to other users by its memory address,
* as this is a very fast 32 or 64 bit integer comparison.
*/
void AddUser(userrec* user);
/** Add a user pointer to the internal reference list of opped users
* @param user The user to add
*/
void AddOppedUser(userrec* user);
/** Add a user pointer to the internal reference list of halfopped users
* @param user The user to add
*/
void AddHalfoppedUser(userrec* user);
/** Add a user pointer to the internal reference list of voiced users
* @param user The user to add
*/
void AddVoicedUser(userrec* user);
/** Delete a user pointer to the internal reference list
* @param user The user to delete
* @return number of users left on the channel after deletion of the user
*/
unsigned long DelUser(userrec* user);
/** Delete a user pointer to the internal reference list of opped users
* @param user The user to delete
*/
void DelOppedUser(userrec* user);
/** Delete a user pointer to the internal reference list of halfopped users
* @param user The user to delete
*/
void DelHalfoppedUser(userrec* user);
/** Delete a user pointer to the internal reference list of voiced users
* @param user The user to delete
*/
void DelVoicedUser(userrec* user);
/** Obtain the internal reference list
* The internal reference list contains a list of userrec*.
* These are used for rapid comparison to determine
* channel membership for PRIVMSG, NOTICE, QUIT, PART etc.
* The resulting pointer to the vector should be considered
* readonly and only modified via AddUser and DelUser.
*
* @return This function returns pointer to a map of userrec pointers (CUList*).
*/
CUList* GetUsers();
/** Obtain the internal reference list of opped users
* @return This function returns pointer to a map of userrec pointers (CUList*).
*/
CUList* GetOppedUsers();
/** Obtain the internal reference list of halfopped users
* @return This function returns pointer to a map of userrec pointers (CUList*).
*/
CUList* GetHalfoppedUsers();
/** Obtain the internal reference list of voiced users
* @return This function returns pointer to a map of userrec pointers (CUList*).
*/
CUList* GetVoicedUsers();
/** Returns true if the user given is on the given channel.
* @param The user to look for
* @return True if the user is on this channel
*/
bool HasUser(userrec* user);
/** Creates a channel record and initialises it with default values
* @throw Nothing at present.
*/
chanrec(InspIRCd* Instance);
/** Make src kick user from this channel with the given reason.
* @param src The source of the kick
* @param user The user being kicked (must be on this channel)
* @param reason The reason for the kick
* @return The number of users left on the channel. If this is zero
* when the method returns, you MUST delete the chanrec immediately!
*/
long KickUser(userrec *src, userrec *user, const char* reason);
/** Make the server kick user from this channel with the given reason.
* @param user The user being kicked (must be on this channel)
* @param reason The reason for the kick
* @param triggerevents True if you wish this kick to trigger module events
* @return The number of users left on the channel. If this is zero
* when the method returns, you MUST delete the chanrec immediately!
*/
long ServerKickUser(userrec* user, const char* reason, bool triggerevents);
/** Part a user from this channel with the given reason.
* If the reason field is NULL, no reason will be sent.
* @param user The user who is parting (must be on this channel)
* @param reason The (optional) part reason
* @return The number of users left on the channel. If this is zero
* when the method returns, you MUST delete the chanrec immediately!
*/
long PartUser(userrec *user, const char* reason = NULL);
/* Join a user to a channel. May be a channel that doesnt exist yet.
* @param user The user to join to the channel.
* @param cn The channel name to join to. Does not have to exist.
* @param key The key of the channel, if given
* @param override If true, override all join restrictions such as +bkil
* @return A pointer to the chanrec the user was joined to. A new chanrec may have
* been created if the channel did not exist before the user was joined to it.
* If the user could not be joined to a channel, the return value may be NULL.
*/
static chanrec* JoinUser(InspIRCd* ServerInstance, userrec *user, const char* cn, bool override, const char* key, time_t TS = 0);
/** Write to a channel, from a user, using va_args for text
* @param user User whos details to prefix the line with
* @param text A printf-style format string which builds the output line without prefix
* @param ... Zero or more POD types
*/
void WriteChannel(userrec* user, char* text, ...);
/** Write to a channel, from a user, using std::string for text
* @param user User whos details to prefix the line with
* @param text A std::string containing the output line without prefix
*/
void WriteChannel(userrec* user, const std::string &text);
/** Write to a channel, from a server, using va_args for text
* @param ServName Server name to prefix the line with
* @param text A printf-style format string which builds the output line without prefix
* @param ... Zero or more POD type
*/
void WriteChannelWithServ(const char* ServName, const char* text, ...);
/** Write to a channel, from a server, using std::string for text
* @param ServName Server name to prefix the line with
* @param text A std::string containing the output line without prefix
*/
void WriteChannelWithServ(const char* ServName, const std::string &text);
/** Write to all users on a channel except a specific user, using va_args for text.
* Internally, this calls WriteAllExcept().
* @param user User whos details to prefix the line with, and to omit from receipt of the message
* @param serversource If this parameter is true, use the local server name as the source of the text, otherwise,
* use the nick!user@host of the user.
* @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone
* @param text A printf-style format string which builds the output line without prefix
* @param ... Zero or more POD type
*/
void WriteAllExceptSender(userrec* user, bool serversource, char status, char* text, ...);
/** Write to all users on a channel except a list of users, using va_args for text
* @param user User whos details to prefix the line with, and to omit from receipt of the message
* @param serversource If this parameter is true, use the local server name as the source of the text, otherwise,
* use the nick!user@host of the user.
* @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone
* @param except_list A list of users NOT to send the text to
* @param text A printf-style format string which builds the output line without prefix
* @param ... Zero or more POD type
*/
void WriteAllExcept(userrec* user, bool serversource, char status, CUList &except_list, char* text, ...);
/** Write to all users on a channel except a specific user, using std::string for text.
* Internally, this calls WriteAllExcept().
* @param user User whos details to prefix the line with, and to omit from receipt of the message
* @param serversource If this parameter is true, use the local server name as the source of the text, otherwise,
* use the nick!user@host of the user.
* @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone
* @param text A std::string containing the output line without prefix
*/
void WriteAllExceptSender(userrec* user, bool serversource, char status, const std::string& text);
/** Write to all users on a channel except a list of users, using std::string for text
* @param user User whos details to prefix the line with, and to omit from receipt of the message
* @param serversource If this parameter is true, use the local server name as the source of the text, otherwise,
* use the nick!user@host of the user.
* @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone
* @param except_list A list of users NOT to send the text to
* @param text A std::string containing the output line without prefix
*/
void WriteAllExcept(userrec* user, bool serversource, char status, CUList &except_list, const std::string& text);
/** Returns the maximum number of bans allowed to be set on this channel
* @return The maximum number of bans allowed
*/
long GetMaxBans();
/** Return the channel's modes with parameters.
* @param showkey If this is set to true, the actual key is shown,
* otherwise it is replaced with '<KEY>'
* @return The channel mode string
*/
char* ChanModes(bool showkey);
/** Spool the NAMES list for this channel to the given user
* @param user The user to spool the NAMES list to
* @param ulist The user list to send, NULL to use the
* channel's default names list of everyone
*/
void UserList(userrec *user, CUList* ulist = NULL);
/** Get the number of invisible users on this channel
* @return Number of invisible users
*/
int CountInvisible();
/** Get a users status on this channel
* @param user The user to look up
* @return One of STATUS_OP, STATUS_HOP, STATUS_VOICE, or zero.
*/
int GetStatus(userrec *user);
/** Get a users status on this channel in a bitmask
* @param user The user to look up
* @return A bitmask containing zero or more of STATUS_OP, STATUS_HOP, STATUS_VOICE
*/
int GetStatusFlags(userrec *user);
/** Get a users prefix on this channel in a string.
* @param user The user to look up
* @return A character array containing the prefix string.
* Unlike GetStatus and GetStatusFlags which will only return the
* core specified modes @, % and + (op, halfop and voice), GetPrefixChar
* will also return module-defined prefixes. If the user has to prefix,
* an empty but non-null string is returned. If the user has multiple
* prefixes, the highest is returned. If you do not recognise the prefix
* character you can get, you can deal with it in a 'proprtional' manner
* compared to known prefixes, using GetPrefixValue().
*/
const char* GetPrefixChar(userrec *user);
/** Return all of a users mode prefixes into a char* string.
* @param user The user to look up
* @return A list of all prefix characters. The prefixes will always
* be in rank order, greatest first, as certain IRC clients require
* this when multiple prefixes are used names lists.
*/
const char* GetAllPrefixChars(userrec* user);
/** Get the value of a users prefix on this channel.
* @param user The user to look up
* @return The module or core-defined value of the users prefix.
* The values for op, halfop and voice status are constants in
* mode.h, and are OP_VALUE, HALFOP_VALUE, and VOICE_VALUE respectively.
* If the value you are given does not match one of these three, it is
* a module-defined mode, and it should be compared in proportion to
* these three constants. For example a value greater than OP_VALUE
* is a prefix of greater 'worth' than ops, and a value less than
* VOICE_VALUE is of lesser 'worth' than a voice.
*/
unsigned int GetPrefixValue(userrec* user);
/** This method removes all prefix characters from a user.
* It will not inform the user or the channel of the removal of prefixes,
* and should be used when the user parts or quits.
* @param user The user to remove all prefixes from
*/
void RemoveAllPrefixes(userrec* user);
/** Add a prefix character to a user.
* Only the core should call this method, usually from
* within the mode parser or when the first user joins
* the channel (to grant ops to them)
* @param user The user to associate the privilage with
* @param prefix The prefix character to associate
* @param prefix_rank The rank (value) of this prefix character
* @param adding True if adding the prefix, false when removing
*/
void SetPrefix(userrec* user, char prefix, unsigned int prefix_rank, bool adding);
/** Check if a user is banned on this channel
* @param user A user to check against the banlist
* @returns True if the user given is banned
*/
bool IsBanned(userrec* user);
/** Clears the cached max bans value
*/
void ResetMaxBans();
/** Destructor for chanrec
*/
virtual ~chanrec() { /* stub */ }
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __CHANNELS_H__ +#define __CHANNELS_H__ + +#include "inspircd_config.h" +#include "base.h" +#include <time.h> +#include <vector> +#include <string> +#include <map> + +/** RFC1459 channel modes + */ +enum ChannelModes { + CM_TOPICLOCK = 't'-65, /* +t: Only operators can change topic */ + CM_NOEXTERNAL = 'n'-65, /* +n: Only users in the channel can message it */ + CM_INVITEONLY = 'i'-65, /* +i: Invite only */ + CM_MODERATED = 'm'-65, /* +m: Only voices and above can talk */ + CM_SECRET = 's'-65, /* +s: Secret channel */ + CM_PRIVATE = 'p'-65, /* +p: Private channel */ + CM_KEY = 'k'-65, /* +k: Keyed channel */ + CM_LIMIT = 'l'-65 /* +l: Maximum user limit */ +}; + +/* Forward declarations - needed */ +class userrec; +class chanrec; + +/** Holds an entry for a ban list, exemption list, or invite list. + * This class contains a single element in a channel list, such as a banlist. + */ +class HostItem : public classbase +{ + public: + /** Time the item was added + */ + time_t set_time; + /** Who added the item + */ + char set_by[NICKMAX]; + /** The actual item data + */ + char data[MAXBUF]; + + HostItem() { /* stub */ } + virtual ~HostItem() { /* stub */ } +}; + +/** A subclass of HostItem designed to hold channel bans (+b) + */ +class BanItem : public HostItem +{ +}; + +/** Holds a complete ban list + */ +typedef std::vector<BanItem> BanList; + +/** A list of users on a channel + */ +typedef std::map<userrec*,std::string> CUList; + +/** Shorthand for CUList::iterator + */ +typedef CUList::iterator CUListIter; + +/** Shorthand for CUList::const_iterator + */ +typedef CUList::const_iterator CUListConstIter; + +/** A list of custom modes parameters on a channel + */ +typedef std::map<char,char*> CustomModeList; + + +/** used to hold a channel and a users modes on that channel, e.g. +v, +h, +o + */ +enum UserChannelModes { + UCMODE_OP = 1, /* Opped user */ + UCMODE_VOICE = 2, /* Voiced user */ + UCMODE_HOP = 4 /* Halfopped user */ +}; + +/* Forward declaration -- required */ +class InspIRCd; + +/** A stored prefix and its rank + */ +typedef std::pair<char, unsigned int> prefixtype; + +/** A list of prefixes set on a user in a channel + */ +typedef std::vector<prefixtype> pfxcontainer; + +/** A list of users with zero or more prefixes set on them + */ +typedef std::map<userrec*, std::vector<prefixtype> > prefixlist; + +/** Holds all relevent information for a channel. + * This class represents a channel, and contains its name, modes, time created, topic, topic set time, + * etc, and an instance of the BanList type. + */ +class CoreExport chanrec : public Extensible +{ + private: + + /** Pointer to creator object + */ + InspIRCd* ServerInstance; + + /** Connect a chanrec to a userrec + */ + static chanrec* ForceChan(InspIRCd* Instance, chanrec* Ptr, userrec* user, const std::string &privs); + + /** Set default modes for the channel on creation + */ + void SetDefaultModes(); + + /** A list of prefixes associated with each user in the channel + * (e.g. &%+ etc) + */ + prefixlist prefixes; + + /** Maximum number of bans (cached) + */ + int maxbans; + + public: + /** The channel's name. + */ + char name[CHANMAX]; + + /** Modes for the channel. + * This is not a null terminated string! It is a hash where + * each item in it represents if a mode is set. For example + * for mode +A, index 0. Use modechar-65 to calculate which + * field to check. + */ + char modes[64]; + + /** User lists. + * There are four user lists, one for + * all the users, one for the ops, one for + * the halfops and another for the voices. + */ + CUList internal_userlist; + + /** Opped users. + * There are four user lists, one for + * all the users, one for the ops, one for + * the halfops and another for the voices. + */ + CUList internal_op_userlist; + + /** Halfopped users. + * There are four user lists, one for + * all the users, one for the ops, one for + * the halfops and another for the voices. + */ + CUList internal_halfop_userlist; + + /** Voiced users. + * There are four user lists, one for + * all the users, one for the ops, one for + * the halfops and another for the voices. + */ + CUList internal_voice_userlist; + + /** Parameters for custom modes. + * One for each custom mode letter. + */ + CustomModeList custom_mode_params; + + /** Channel topic. + * If this is an empty string, no channel topic is set. + */ + char topic[MAXTOPIC]; + + /** Creation time. + * This is a timestamp (TS) value. + */ + time_t created; + + /** Time topic was set. + * If no topic was ever set, this will be equal to chanrec::created + */ + time_t topicset; + + /** The last user to set the topic. + * If this member is an empty string, no topic was ever set. + */ + char setby[128]; + + /** Contains the channel user limit. + * If this value is zero, there is no limit in place. + */ + short int limit; + + /** Contains the channel key. + * If this value is an empty string, there is no channel key in place. + */ + char key[32]; + + /** The list of all bans set on the channel. + */ + BanList bans; + + /** Sets or unsets a custom mode in the channels info + * @param mode The mode character to set or unset + * @param mode_on True if you want to set the mode or false if you want to remove it + */ + void SetMode(char mode,bool mode_on); + + /** Sets or unsets the parameters for a custom mode in a channels info + * @param mode The mode character to set or unset + * @param parameter The parameter string to associate with this mode character + * @param mode_on True if you want to set the mode or false if you want to remove it + */ + void SetModeParam(char mode,const char* parameter,bool mode_on); + + /** Returns true if a mode is set on a channel + * @param mode The mode character you wish to query + * @return True if the custom mode is set, false if otherwise + */ + bool IsModeSet(char mode); + + /** Returns the parameter for a custom mode on a channel. + * @param mode The mode character you wish to query + * + * For example if "+L #foo" is set, and you pass this method + * 'L', it will return '#foo'. If the mode is not set on the + * channel, or the mode has no parameters associated with it, + * it will return an empty string. + * + * @return The parameter for this mode is returned, or an empty string + */ + std::string GetModeParameter(char mode); + + /** Obtain the channel "user counter" + * This returns the channel reference counter, which is initialized + * to 0 when the channel is created and incremented/decremented + * upon joins, parts quits and kicks. + * + * @return The number of users on this channel + */ + long GetUserCounter(); + + /** Add a user pointer to the internal reference list + * @param user The user to add + * + * The data inserted into the reference list is a table as it is + * an arbitary pointer compared to other users by its memory address, + * as this is a very fast 32 or 64 bit integer comparison. + */ + void AddUser(userrec* user); + + /** Add a user pointer to the internal reference list of opped users + * @param user The user to add + */ + void AddOppedUser(userrec* user); + + /** Add a user pointer to the internal reference list of halfopped users + * @param user The user to add + */ + void AddHalfoppedUser(userrec* user); + + /** Add a user pointer to the internal reference list of voiced users + * @param user The user to add + */ + void AddVoicedUser(userrec* user); + + /** Delete a user pointer to the internal reference list + * @param user The user to delete + * @return number of users left on the channel after deletion of the user + */ + unsigned long DelUser(userrec* user); + + /** Delete a user pointer to the internal reference list of opped users + * @param user The user to delete + */ + void DelOppedUser(userrec* user); + + /** Delete a user pointer to the internal reference list of halfopped users + * @param user The user to delete + */ + void DelHalfoppedUser(userrec* user); + + /** Delete a user pointer to the internal reference list of voiced users + * @param user The user to delete + */ + void DelVoicedUser(userrec* user); + + /** Obtain the internal reference list + * The internal reference list contains a list of userrec*. + * These are used for rapid comparison to determine + * channel membership for PRIVMSG, NOTICE, QUIT, PART etc. + * The resulting pointer to the vector should be considered + * readonly and only modified via AddUser and DelUser. + * + * @return This function returns pointer to a map of userrec pointers (CUList*). + */ + CUList* GetUsers(); + + /** Obtain the internal reference list of opped users + * @return This function returns pointer to a map of userrec pointers (CUList*). + */ + CUList* GetOppedUsers(); + + /** Obtain the internal reference list of halfopped users + * @return This function returns pointer to a map of userrec pointers (CUList*). + */ + CUList* GetHalfoppedUsers(); + + /** Obtain the internal reference list of voiced users + * @return This function returns pointer to a map of userrec pointers (CUList*). + */ + CUList* GetVoicedUsers(); + + /** Returns true if the user given is on the given channel. + * @param The user to look for + * @return True if the user is on this channel + */ + bool HasUser(userrec* user); + + /** Creates a channel record and initialises it with default values + * @throw Nothing at present. + */ + chanrec(InspIRCd* Instance); + + /** Make src kick user from this channel with the given reason. + * @param src The source of the kick + * @param user The user being kicked (must be on this channel) + * @param reason The reason for the kick + * @return The number of users left on the channel. If this is zero + * when the method returns, you MUST delete the chanrec immediately! + */ + long KickUser(userrec *src, userrec *user, const char* reason); + + /** Make the server kick user from this channel with the given reason. + * @param user The user being kicked (must be on this channel) + * @param reason The reason for the kick + * @param triggerevents True if you wish this kick to trigger module events + * @return The number of users left on the channel. If this is zero + * when the method returns, you MUST delete the chanrec immediately! + */ + long ServerKickUser(userrec* user, const char* reason, bool triggerevents); + + /** Part a user from this channel with the given reason. + * If the reason field is NULL, no reason will be sent. + * @param user The user who is parting (must be on this channel) + * @param reason The (optional) part reason + * @return The number of users left on the channel. If this is zero + * when the method returns, you MUST delete the chanrec immediately! + */ + long PartUser(userrec *user, const char* reason = NULL); + + /* Join a user to a channel. May be a channel that doesnt exist yet. + * @param user The user to join to the channel. + * @param cn The channel name to join to. Does not have to exist. + * @param key The key of the channel, if given + * @param override If true, override all join restrictions such as +bkil + * @return A pointer to the chanrec the user was joined to. A new chanrec may have + * been created if the channel did not exist before the user was joined to it. + * If the user could not be joined to a channel, the return value may be NULL. + */ + static chanrec* JoinUser(InspIRCd* ServerInstance, userrec *user, const char* cn, bool override, const char* key, time_t TS = 0); + + /** Write to a channel, from a user, using va_args for text + * @param user User whos details to prefix the line with + * @param text A printf-style format string which builds the output line without prefix + * @param ... Zero or more POD types + */ + void WriteChannel(userrec* user, char* text, ...); + + /** Write to a channel, from a user, using std::string for text + * @param user User whos details to prefix the line with + * @param text A std::string containing the output line without prefix + */ + void WriteChannel(userrec* user, const std::string &text); + + /** Write to a channel, from a server, using va_args for text + * @param ServName Server name to prefix the line with + * @param text A printf-style format string which builds the output line without prefix + * @param ... Zero or more POD type + */ + void WriteChannelWithServ(const char* ServName, const char* text, ...); + + /** Write to a channel, from a server, using std::string for text + * @param ServName Server name to prefix the line with + * @param text A std::string containing the output line without prefix + */ + void WriteChannelWithServ(const char* ServName, const std::string &text); + + /** Write to all users on a channel except a specific user, using va_args for text. + * Internally, this calls WriteAllExcept(). + * @param user User whos details to prefix the line with, and to omit from receipt of the message + * @param serversource If this parameter is true, use the local server name as the source of the text, otherwise, + * use the nick!user@host of the user. + * @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone + * @param text A printf-style format string which builds the output line without prefix + * @param ... Zero or more POD type + */ + void WriteAllExceptSender(userrec* user, bool serversource, char status, char* text, ...); + + /** Write to all users on a channel except a list of users, using va_args for text + * @param user User whos details to prefix the line with, and to omit from receipt of the message + * @param serversource If this parameter is true, use the local server name as the source of the text, otherwise, + * use the nick!user@host of the user. + * @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone + * @param except_list A list of users NOT to send the text to + * @param text A printf-style format string which builds the output line without prefix + * @param ... Zero or more POD type + */ + void WriteAllExcept(userrec* user, bool serversource, char status, CUList &except_list, char* text, ...); + + /** Write to all users on a channel except a specific user, using std::string for text. + * Internally, this calls WriteAllExcept(). + * @param user User whos details to prefix the line with, and to omit from receipt of the message + * @param serversource If this parameter is true, use the local server name as the source of the text, otherwise, + * use the nick!user@host of the user. + * @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone + * @param text A std::string containing the output line without prefix + */ + void WriteAllExceptSender(userrec* user, bool serversource, char status, const std::string& text); + + /** Write to all users on a channel except a list of users, using std::string for text + * @param user User whos details to prefix the line with, and to omit from receipt of the message + * @param serversource If this parameter is true, use the local server name as the source of the text, otherwise, + * use the nick!user@host of the user. + * @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone + * @param except_list A list of users NOT to send the text to + * @param text A std::string containing the output line without prefix + */ + void WriteAllExcept(userrec* user, bool serversource, char status, CUList &except_list, const std::string& text); + + /** Returns the maximum number of bans allowed to be set on this channel + * @return The maximum number of bans allowed + */ + long GetMaxBans(); + + /** Return the channel's modes with parameters. + * @param showkey If this is set to true, the actual key is shown, + * otherwise it is replaced with '<KEY>' + * @return The channel mode string + */ + char* ChanModes(bool showkey); + + /** Spool the NAMES list for this channel to the given user + * @param user The user to spool the NAMES list to + * @param ulist The user list to send, NULL to use the + * channel's default names list of everyone + */ + void UserList(userrec *user, CUList* ulist = NULL); + + /** Get the number of invisible users on this channel + * @return Number of invisible users + */ + int CountInvisible(); + + /** Get a users status on this channel + * @param user The user to look up + * @return One of STATUS_OP, STATUS_HOP, STATUS_VOICE, or zero. + */ + int GetStatus(userrec *user); + + /** Get a users status on this channel in a bitmask + * @param user The user to look up + * @return A bitmask containing zero or more of STATUS_OP, STATUS_HOP, STATUS_VOICE + */ + int GetStatusFlags(userrec *user); + + /** Get a users prefix on this channel in a string. + * @param user The user to look up + * @return A character array containing the prefix string. + * Unlike GetStatus and GetStatusFlags which will only return the + * core specified modes @, % and + (op, halfop and voice), GetPrefixChar + * will also return module-defined prefixes. If the user has to prefix, + * an empty but non-null string is returned. If the user has multiple + * prefixes, the highest is returned. If you do not recognise the prefix + * character you can get, you can deal with it in a 'proprtional' manner + * compared to known prefixes, using GetPrefixValue(). + */ + const char* GetPrefixChar(userrec *user); + + /** Return all of a users mode prefixes into a char* string. + * @param user The user to look up + * @return A list of all prefix characters. The prefixes will always + * be in rank order, greatest first, as certain IRC clients require + * this when multiple prefixes are used names lists. + */ + const char* GetAllPrefixChars(userrec* user); + + /** Get the value of a users prefix on this channel. + * @param user The user to look up + * @return The module or core-defined value of the users prefix. + * The values for op, halfop and voice status are constants in + * mode.h, and are OP_VALUE, HALFOP_VALUE, and VOICE_VALUE respectively. + * If the value you are given does not match one of these three, it is + * a module-defined mode, and it should be compared in proportion to + * these three constants. For example a value greater than OP_VALUE + * is a prefix of greater 'worth' than ops, and a value less than + * VOICE_VALUE is of lesser 'worth' than a voice. + */ + unsigned int GetPrefixValue(userrec* user); + + /** This method removes all prefix characters from a user. + * It will not inform the user or the channel of the removal of prefixes, + * and should be used when the user parts or quits. + * @param user The user to remove all prefixes from + */ + void RemoveAllPrefixes(userrec* user); + + /** Add a prefix character to a user. + * Only the core should call this method, usually from + * within the mode parser or when the first user joins + * the channel (to grant ops to them) + * @param user The user to associate the privilage with + * @param prefix The prefix character to associate + * @param prefix_rank The rank (value) of this prefix character + * @param adding True if adding the prefix, false when removing + */ + void SetPrefix(userrec* user, char prefix, unsigned int prefix_rank, bool adding); + + /** Check if a user is banned on this channel + * @param user A user to check against the banlist + * @returns True if the user given is banned + */ + bool IsBanned(userrec* user); + + /** Clears the cached max bans value + */ + void ResetMaxBans(); + + /** Destructor for chanrec + */ + virtual ~chanrec() { /* stub */ } +}; + +#endif diff --git a/include/command_parse.h b/include/command_parse.h index ab567642e..e8240fcf9 100644 --- a/include/command_parse.h +++ b/include/command_parse.h @@ -1 +1,244 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __COMMAND_PARSE_H
#define __COMMAND_PARSE_H
#include <string>
#include "users.h"
#include "ctables.h"
#include "typedefs.h"
/** Required forward declaration
*/
class InspIRCd;
/** A list of dll/so files containing the command handlers for the core
*/
typedef std::map<std::string, void*> SharedObjectList;
/** This class handles command management and parsing.
* It allows you to add and remove commands from the map,
* call command handlers by name, and chop up comma seperated
* parameters into multiple calls.
*/
class CoreExport CommandParser : public classbase
{
private:
/** The creator of this class
*/
InspIRCd* ServerInstance;
/** Parameter buffer
*/
std::vector<std::string> para;
/** Process a parameter string into a list of items
* @param command_p The output list of items
* @param parameters The input string
* @return The number of parameters parsed into command_p
*/
int ProcessParameters(char **command_p,char *parameters);
/** Process a command from a user.
* @param user The user to parse the command for
* @param cmd The command string to process
*/
void ProcessCommand(userrec *user, std::string &cmd);
/** Insert the default RFC1459 commands into the command hash.
*/
void SetupCommandTable();
/** Finds the init_command symbol in a .so file
* @param v A function pointer to be initialized
* @param h A valid shared object handle
* @return True if the symbol could be found
*/
bool FindSym(void** v, void* h);
/** A list of core-implemented modes and their shared object handles
*/
SharedObjectList RFCCommands;
/** Load a command from a shared object on disk.
* @param name The shared object to load (without path)
*/
void LoadCommand(const char* name);
/** Removes a command if the sources match. Used as a helper for
* safe hash_map delete while iter in RemoveCommands(const char* source).
*/
void RemoveCommand(nspace::hash_map<std::string,command_t*>::iterator safei, const char* source);
public:
/** Command list, a hash_map of command names to command_t*
*/
command_table cmdlist;
/** Reload a core command.
* This will only reload commands implemented by the core,
* to reload a modular command, you must reload that module.
* @param cmd The command to reload. This will cause the shared
* object which implements this command to be closed, and then reloaded.
* @return True if the command was reloaded, false if it could not be found
* or another error occured
*/
bool ReloadCommand(const char* cmd);
/** Default constructor.
* @param Instance The creator of this class
*/
CommandParser(InspIRCd* Instance);
/** Calls the handler for a given command.
* @param commandname The command to find. This should be in uppercase.
* @param parameters Parameter list as an array of array of char (that's not a typo).
* @param pcnt The number of items in the parameters list
* @param user The user to call the handler on behalf of
* @return This method will return CMD_SUCCESS if the command handler was found and called,
* and the command completeld successfully. It will return CMD_FAILURE if the command handler was found
* and called, but the command did not complete successfully, and it will return CMD_INVALID if the
* command simply did not exist at all or the wrong number of parameters were given, or the user
* was not privilaged enough to execute the command.
*/
CmdResult CallHandler(const std::string &commandname,const char** parameters, int pcnt, userrec *user);
/** Get the handler function for a command.
* @param commandname The command required. Always use uppercase for this parameter.
* @return a pointer to the command handler, or NULL
*/
command_t* GetHandler(const std::string &commandname);
/** This function returns true if a command is valid with the given number of parameters and user.
* @param commandname The command name to check
* @param pcnt The parameter count
* @param user The user to check against
* @return If the user given has permission to execute the command, and the parameter count is
* equal to or greater than the minimum number of parameters to the given command, then this
* function will return true, otherwise it will return false.
*/
bool IsValidCommand(const std::string &commandname, int pcnt, userrec * user);
/** LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list.
* There are two overriden versions of this method, one of which takes two potential lists and the other takes one.
* We need a version which takes two potential lists for JOIN, because a JOIN may contain two lists of items at once,
* the channel names and their keys as follows:
*
* JOIN #chan1,#chan2,#chan3 key1,,key3
*
* Therefore, we need to deal with both lists concurrently. The first instance of this method does that by creating
* two instances of irc::commasepstream and reading them both together until the first runs out of tokens.
* The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc.
* Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam.
*
* @param user The user who sent the command
* @param CommandObj the command object to call for each parameter in the list
* @param parameters Parameter list as an array of array of char (that's not a typo).
* @param The number of items in the parameters list
* @param splithere The first parameter index to split as a comma seperated list
* @param extra The second parameter index to split as a comma seperated list
* @return This function will return 1 when there are no more parameters to process. When this occurs, its
* caller should return without doing anything, otherwise it should continue into its main section of code.
*/
int LoopCall(userrec* user, command_t* CommandObj, const char** parameters, int pcnt, unsigned int splithere, unsigned int extra);
/** LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list.
* There are two overriden versions of this method, one of which takes two potential lists and the other takes one.
* We need a version which takes two potential lists for JOIN, because a JOIN may contain two lists of items at once,
* the channel names and their keys as follows:
*
* JOIN #chan1,#chan2,#chan3 key1,,key3
*
* Therefore, we need to deal with both lists concurrently. The first instance of this method does that by creating
* two instances of irc::commasepstream and reading them both together until the first runs out of tokens.
* The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc.
* Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam.
*
* @param user The user who sent the command
* @param CommandObj the command object to call for each parameter in the list
* @param parameters Parameter list as an array of array of char (that's not a typo).
* @param The number of items in the parameters list
* @param splithere The first parameter index to split as a comma seperated list
* @param extra The second parameter index to split as a comma seperated list
* @return This function will return 1 when there are no more parameters to process. When this occurs, its
* caller should return without doing anything, otherwise it should continue into its main section of code.
*/
int LoopCall(userrec* user, command_t* CommandObj, const char** parameters, int pcnt, unsigned int splithere);
/** Take a raw input buffer from a recvq, and process it on behalf of a user.
* @param buffer The buffer line to process
* @param user The user to whom this line belongs
*/
void ProcessBuffer(std::string &buffer,userrec *user);
/** Remove all commands relating to module 'source'.
* @param source A module name which has introduced new commands
* @return True This function returns true if commands were removed
*/
bool RemoveCommands(const char* source);
/** Add a new command to the commands hash
* @param f The new command_t to add to the list
* @param so_handle The handle to the shared object where the command can be found.
* Only core commands loaded via cmd_*.so files should set this parameter to anything
* meaningful. Module authors should leave this parameter at its default of NULL.
* @return True if the command was added
*/
bool CreateCommand(command_t *f, void* so_handle = NULL);
};
/** Command handler class for the RELOAD command.
* A command cant really reload itself, so this has to be in here.
*/
class cmd_reload : public command_t
{
public:
/** Standard constructor
*/
cmd_reload (InspIRCd* Instance) : command_t(Instance,"RELOAD",'o',1) { syntax = "<core-command>"; }
/** Handle RELOAD
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
/** A lookup table of values for multiplier characters used by
* InspIRCd::Duration(). In this lookup table, the indexes for
* the ascii values 'm' and 'M' have the value '60', the indexes
* for the ascii values 'D' and 'd' have a value of '86400', etc.
*/
const int duration_multi[] =
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 86400, 1, 1, 1, 3600,
1, 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1,
604800, 1, 31536000, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 86400, 1, 1, 1, 3600, 1, 1, 1, 1, 60,
1, 1, 1, 1, 1, 1, 1, 1, 1, 604800, 1, 31536000,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __COMMAND_PARSE_H +#define __COMMAND_PARSE_H + +#include <string> +#include "users.h" +#include "ctables.h" +#include "typedefs.h" + +/** Required forward declaration + */ +class InspIRCd; + +/** A list of dll/so files containing the command handlers for the core + */ +typedef std::map<std::string, void*> SharedObjectList; + +/** This class handles command management and parsing. + * It allows you to add and remove commands from the map, + * call command handlers by name, and chop up comma seperated + * parameters into multiple calls. + */ +class CoreExport CommandParser : public classbase +{ + private: + /** The creator of this class + */ + InspIRCd* ServerInstance; + + /** Parameter buffer + */ + std::vector<std::string> para; + + /** Process a parameter string into a list of items + * @param command_p The output list of items + * @param parameters The input string + * @return The number of parameters parsed into command_p + */ + int ProcessParameters(char **command_p,char *parameters); + + /** Process a command from a user. + * @param user The user to parse the command for + * @param cmd The command string to process + */ + void ProcessCommand(userrec *user, std::string &cmd); + + /** Insert the default RFC1459 commands into the command hash. + */ + void SetupCommandTable(); + + /** Finds the init_command symbol in a .so file + * @param v A function pointer to be initialized + * @param h A valid shared object handle + * @return True if the symbol could be found + */ + bool FindSym(void** v, void* h); + + /** A list of core-implemented modes and their shared object handles + */ + SharedObjectList RFCCommands; + + /** Load a command from a shared object on disk. + * @param name The shared object to load (without path) + */ + void LoadCommand(const char* name); + + /** Removes a command if the sources match. Used as a helper for + * safe hash_map delete while iter in RemoveCommands(const char* source). + */ + void RemoveCommand(nspace::hash_map<std::string,command_t*>::iterator safei, const char* source); + + + public: + /** Command list, a hash_map of command names to command_t* + */ + command_table cmdlist; + + /** Reload a core command. + * This will only reload commands implemented by the core, + * to reload a modular command, you must reload that module. + * @param cmd The command to reload. This will cause the shared + * object which implements this command to be closed, and then reloaded. + * @return True if the command was reloaded, false if it could not be found + * or another error occured + */ + bool ReloadCommand(const char* cmd); + + /** Default constructor. + * @param Instance The creator of this class + */ + CommandParser(InspIRCd* Instance); + + /** Calls the handler for a given command. + * @param commandname The command to find. This should be in uppercase. + * @param parameters Parameter list as an array of array of char (that's not a typo). + * @param pcnt The number of items in the parameters list + * @param user The user to call the handler on behalf of + * @return This method will return CMD_SUCCESS if the command handler was found and called, + * and the command completeld successfully. It will return CMD_FAILURE if the command handler was found + * and called, but the command did not complete successfully, and it will return CMD_INVALID if the + * command simply did not exist at all or the wrong number of parameters were given, or the user + * was not privilaged enough to execute the command. + */ + CmdResult CallHandler(const std::string &commandname,const char** parameters, int pcnt, userrec *user); + + /** Get the handler function for a command. + * @param commandname The command required. Always use uppercase for this parameter. + * @return a pointer to the command handler, or NULL + */ + command_t* GetHandler(const std::string &commandname); + + /** This function returns true if a command is valid with the given number of parameters and user. + * @param commandname The command name to check + * @param pcnt The parameter count + * @param user The user to check against + * @return If the user given has permission to execute the command, and the parameter count is + * equal to or greater than the minimum number of parameters to the given command, then this + * function will return true, otherwise it will return false. + */ + bool IsValidCommand(const std::string &commandname, int pcnt, userrec * user); + + /** LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list. + * There are two overriden versions of this method, one of which takes two potential lists and the other takes one. + * We need a version which takes two potential lists for JOIN, because a JOIN may contain two lists of items at once, + * the channel names and their keys as follows: + * + * JOIN #chan1,#chan2,#chan3 key1,,key3 + * + * Therefore, we need to deal with both lists concurrently. The first instance of this method does that by creating + * two instances of irc::commasepstream and reading them both together until the first runs out of tokens. + * The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc. + * Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam. + * + * @param user The user who sent the command + * @param CommandObj the command object to call for each parameter in the list + * @param parameters Parameter list as an array of array of char (that's not a typo). + * @param The number of items in the parameters list + * @param splithere The first parameter index to split as a comma seperated list + * @param extra The second parameter index to split as a comma seperated list + * @return This function will return 1 when there are no more parameters to process. When this occurs, its + * caller should return without doing anything, otherwise it should continue into its main section of code. + */ + int LoopCall(userrec* user, command_t* CommandObj, const char** parameters, int pcnt, unsigned int splithere, unsigned int extra); + + /** LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list. + * There are two overriden versions of this method, one of which takes two potential lists and the other takes one. + * We need a version which takes two potential lists for JOIN, because a JOIN may contain two lists of items at once, + * the channel names and their keys as follows: + * + * JOIN #chan1,#chan2,#chan3 key1,,key3 + * + * Therefore, we need to deal with both lists concurrently. The first instance of this method does that by creating + * two instances of irc::commasepstream and reading them both together until the first runs out of tokens. + * The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc. + * Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam. + * + * @param user The user who sent the command + * @param CommandObj the command object to call for each parameter in the list + * @param parameters Parameter list as an array of array of char (that's not a typo). + * @param The number of items in the parameters list + * @param splithere The first parameter index to split as a comma seperated list + * @param extra The second parameter index to split as a comma seperated list + * @return This function will return 1 when there are no more parameters to process. When this occurs, its + * caller should return without doing anything, otherwise it should continue into its main section of code. + */ + int LoopCall(userrec* user, command_t* CommandObj, const char** parameters, int pcnt, unsigned int splithere); + + /** Take a raw input buffer from a recvq, and process it on behalf of a user. + * @param buffer The buffer line to process + * @param user The user to whom this line belongs + */ + void ProcessBuffer(std::string &buffer,userrec *user); + + /** Remove all commands relating to module 'source'. + * @param source A module name which has introduced new commands + * @return True This function returns true if commands were removed + */ + bool RemoveCommands(const char* source); + + /** Add a new command to the commands hash + * @param f The new command_t to add to the list + * @param so_handle The handle to the shared object where the command can be found. + * Only core commands loaded via cmd_*.so files should set this parameter to anything + * meaningful. Module authors should leave this parameter at its default of NULL. + * @return True if the command was added + */ + bool CreateCommand(command_t *f, void* so_handle = NULL); +}; + +/** Command handler class for the RELOAD command. + * A command cant really reload itself, so this has to be in here. + */ +class cmd_reload : public command_t +{ + public: + /** Standard constructor + */ + cmd_reload (InspIRCd* Instance) : command_t(Instance,"RELOAD",'o',1) { syntax = "<core-command>"; } + /** Handle RELOAD + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +/** A lookup table of values for multiplier characters used by + * InspIRCd::Duration(). In this lookup table, the indexes for + * the ascii values 'm' and 'M' have the value '60', the indexes + * for the ascii values 'D' and 'd' have a value of '86400', etc. + */ +const int duration_multi[] = +{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 86400, 1, 1, 1, 3600, + 1, 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 604800, 1, 31536000, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 86400, 1, 1, 1, 3600, 1, 1, 1, 1, 60, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 604800, 1, 31536000, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + +#endif + diff --git a/include/commands/cmd_admin.h b/include/commands/cmd_admin.h index d251891f8..108c4aa9f 100644 --- a/include/commands/cmd_admin.h +++ b/include/commands/cmd_admin.h @@ -1 +1,44 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_ADMIN_H__
#define __CMD_ADMIN_H__
#include "users.h"
#include "channels.h"
#include "ctables.h"
/** Handle /ADMIN. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_admin : public command_t
{
public:
/** Constructor for admin.
*/
cmd_admin (InspIRCd* Instance) : command_t(Instance,"ADMIN",0,0) { syntax = "[<servername>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_ADMIN_H__ +#define __CMD_ADMIN_H__ + +#include "users.h" +#include "channels.h" +#include "ctables.h" + +/** Handle /ADMIN. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_admin : public command_t +{ + public: + /** Constructor for admin. + */ + cmd_admin (InspIRCd* Instance) : command_t(Instance,"ADMIN",0,0) { syntax = "[<servername>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_away.h b/include/commands/cmd_away.h index ce6a66abd..88d111c78 100644 --- a/include/commands/cmd_away.h +++ b/include/commands/cmd_away.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_AWAY_H__
#define __CMD_AWAY_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /AWAY. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_away : public command_t
{
public:
/** Constructor for away.
*/
cmd_away (InspIRCd* Instance) : command_t(Instance,"AWAY",0,0) { syntax = "[<message>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_AWAY_H__ +#define __CMD_AWAY_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /AWAY. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_away : public command_t +{ + public: + /** Constructor for away. + */ + cmd_away (InspIRCd* Instance) : command_t(Instance,"AWAY",0,0) { syntax = "[<message>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_clearcache.h b/include/commands/cmd_clearcache.h index abf5b8a54..6c5d66ac8 100644 --- a/include/commands/cmd_clearcache.h +++ b/include/commands/cmd_clearcache.h @@ -1 +1,44 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_ADMIN_H__
#define __CMD_ADMIN_H__
#include "users.h"
#include "channels.h"
#include "ctables.h"
/** Handle /ADMIN. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_clearcache : public command_t
{
public:
/** Constructor for clearcache.
*/
cmd_clearcache (InspIRCd* Instance) : command_t(Instance,"CLEARCACHE",'o',0) { }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_ADMIN_H__ +#define __CMD_ADMIN_H__ + +#include "users.h" +#include "channels.h" +#include "ctables.h" + +/** Handle /ADMIN. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_clearcache : public command_t +{ + public: + /** Constructor for clearcache. + */ + cmd_clearcache (InspIRCd* Instance) : command_t(Instance,"CLEARCACHE",'o',0) { } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_commands.h b/include/commands/cmd_commands.h index 095a88557..62359dd5d 100644 --- a/include/commands/cmd_commands.h +++ b/include/commands/cmd_commands.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_COMMANDS_H__
#define __CMD_COMMANDS_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /COMMANDS. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_commands : public command_t
{
public:
/** Constructor for commands.
*/
cmd_commands (InspIRCd* Instance) : command_t(Instance,"COMMANDS",0,0) { }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_COMMANDS_H__ +#define __CMD_COMMANDS_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /COMMANDS. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_commands : public command_t +{ + public: + /** Constructor for commands. + */ + cmd_commands (InspIRCd* Instance) : command_t(Instance,"COMMANDS",0,0) { } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_connect.h b/include/commands/cmd_connect.h index bcb25c15a..01150fc68 100644 --- a/include/commands/cmd_connect.h +++ b/include/commands/cmd_connect.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_CONNECT_H__
#define __CMD_CONNECT_H__
#include "users.h"
#include "channels.h"
#include "ctables.h"
#include "modules.h"
/** Handle /CONNECT. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_connect : public command_t
{
public:
/** Constructor for connect.
*/
cmd_connect (InspIRCd* Instance) : command_t(Instance,"CONNECT",'o',1) { syntax = "<servername> [<remote-server>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_CONNECT_H__ +#define __CMD_CONNECT_H__ + +#include "users.h" +#include "channels.h" +#include "ctables.h" +#include "modules.h" + +/** Handle /CONNECT. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_connect : public command_t +{ + public: + /** Constructor for connect. + */ + cmd_connect (InspIRCd* Instance) : command_t(Instance,"CONNECT",'o',1) { syntax = "<servername> [<remote-server>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_die.h b/include/commands/cmd_die.h index 3d88ec4c1..e3ee3ab9d 100644 --- a/include/commands/cmd_die.h +++ b/include/commands/cmd_die.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_DIE_H__
#define __CMD_DIE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /DIE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_die : public command_t
{
public:
/** Constructor for die.
*/
cmd_die (InspIRCd* Instance) : command_t(Instance,"DIE",'o',1) { syntax = "<password>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_DIE_H__ +#define __CMD_DIE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /DIE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_die : public command_t +{ + public: + /** Constructor for die. + */ + cmd_die (InspIRCd* Instance) : command_t(Instance,"DIE",'o',1) { syntax = "<password>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_eline.h b/include/commands/cmd_eline.h index 23fae3f03..594af9697 100644 --- a/include/commands/cmd_eline.h +++ b/include/commands/cmd_eline.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_ELINE_H__
#define __CMD_ELINE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /ELINE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_eline : public command_t
{
public:
/** Constructor for eline.
*/
cmd_eline (InspIRCd* Instance) : command_t(Instance,"ELINE",'o',1) { syntax = "<ident@host> [<duration> :<reason>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_ELINE_H__ +#define __CMD_ELINE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /ELINE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_eline : public command_t +{ + public: + /** Constructor for eline. + */ + cmd_eline (InspIRCd* Instance) : command_t(Instance,"ELINE",'o',1) { syntax = "<ident@host> [<duration> :<reason>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_gline.h b/include/commands/cmd_gline.h index f8a82dfa8..5fc8eccee 100644 --- a/include/commands/cmd_gline.h +++ b/include/commands/cmd_gline.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_GLINE_H__
#define __CMD_GLINE_H__
// include the common header file
#include "users.h"
#include "channels.h"
/** Handle /GLINE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_gline : public command_t
{
public:
/** Constructor for gline.
*/
cmd_gline (InspIRCd* Instance) : command_t(Instance,"GLINE",'o',1) { syntax = "<ident@host> [<duration> :<reason>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_GLINE_H__ +#define __CMD_GLINE_H__ + +// include the common header file + +#include "users.h" +#include "channels.h" + +/** Handle /GLINE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_gline : public command_t +{ + public: + /** Constructor for gline. + */ + cmd_gline (InspIRCd* Instance) : command_t(Instance,"GLINE",'o',1) { syntax = "<ident@host> [<duration> :<reason>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_info.h b/include/commands/cmd_info.h index 00bb6d2f2..330c8bcf1 100644 --- a/include/commands/cmd_info.h +++ b/include/commands/cmd_info.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_INFO_H__
#define __CMD_INFO_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /INFO. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_info : public command_t
{
public:
/** Constructor for info.
*/
cmd_info (InspIRCd* Instance) : command_t(Instance,"INFO",0,0) { syntax = "[<servermask>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_INFO_H__ +#define __CMD_INFO_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /INFO. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_info : public command_t +{ + public: + /** Constructor for info. + */ + cmd_info (InspIRCd* Instance) : command_t(Instance,"INFO",0,0) { syntax = "[<servermask>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_invite.h b/include/commands/cmd_invite.h index db506fee9..13bd1f35b 100644 --- a/include/commands/cmd_invite.h +++ b/include/commands/cmd_invite.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_INVITE_H__
#define __CMD_INVITE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /INVITE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_invite : public command_t
{
public:
/** Constructor for invite.
*/
cmd_invite (InspIRCd* Instance) : command_t(Instance,"INVITE",0,0) { syntax = "[<nick> <channel>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_INVITE_H__ +#define __CMD_INVITE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /INVITE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_invite : public command_t +{ + public: + /** Constructor for invite. + */ + cmd_invite (InspIRCd* Instance) : command_t(Instance,"INVITE",0,0) { syntax = "[<nick> <channel>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_ison.h b/include/commands/cmd_ison.h index 143a3efd7..d0be58c23 100644 --- a/include/commands/cmd_ison.h +++ b/include/commands/cmd_ison.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_ISON_H__
#define __CMD_ISON_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /ISON. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_ison : public command_t
{
public:
/** Constructor for ison.
*/
cmd_ison (InspIRCd* Instance) : command_t(Instance,"ISON",0,0) { syntax = "<nick> {nick}"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_ISON_H__ +#define __CMD_ISON_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /ISON. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_ison : public command_t +{ + public: + /** Constructor for ison. + */ + cmd_ison (InspIRCd* Instance) : command_t(Instance,"ISON",0,0) { syntax = "<nick> {nick}"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_join.h b/include/commands/cmd_join.h index 65abdff59..6e343bb72 100644 --- a/include/commands/cmd_join.h +++ b/include/commands/cmd_join.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_JOIN_H__
#define __CMD_JOIN_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /JOIN. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_join : public command_t
{
public:
/** Constructor for join.
*/
cmd_join (InspIRCd* Instance) : command_t(Instance,"JOIN",0,1) { syntax = "<channel>{,<channel>} {<key>{,<key>}}"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_JOIN_H__ +#define __CMD_JOIN_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /JOIN. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_join : public command_t +{ + public: + /** Constructor for join. + */ + cmd_join (InspIRCd* Instance) : command_t(Instance,"JOIN",0,1) { syntax = "<channel>{,<channel>} {<key>{,<key>}}"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_kick.h b/include/commands/cmd_kick.h index c8832f042..6a44d0c12 100644 --- a/include/commands/cmd_kick.h +++ b/include/commands/cmd_kick.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_KICK_H__
#define __CMD_KICK_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /KICK. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_kick : public command_t
{
public:
/** Constructor for kick.
*/
cmd_kick (InspIRCd* Instance) : command_t(Instance,"KICK",0,2) { syntax = "<channel> <nick>{,<nick>} [<reason>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_KICK_H__ +#define __CMD_KICK_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /KICK. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_kick : public command_t +{ + public: + /** Constructor for kick. + */ + cmd_kick (InspIRCd* Instance) : command_t(Instance,"KICK",0,2) { syntax = "<channel> <nick>{,<nick>} [<reason>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_kill.h b/include/commands/cmd_kill.h index 456744c26..8489599b6 100644 --- a/include/commands/cmd_kill.h +++ b/include/commands/cmd_kill.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_KILL_H__
#define __CMD_KILL_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /KILL. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_kill : public command_t
{
public:
/** Constructor for kill.
*/
cmd_kill (InspIRCd* Instance) : command_t(Instance,"KILL",'o',2) { syntax = "<nickname> <reason>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_KILL_H__ +#define __CMD_KILL_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /KILL. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_kill : public command_t +{ + public: + /** Constructor for kill. + */ + cmd_kill (InspIRCd* Instance) : command_t(Instance,"KILL",'o',2) { syntax = "<nickname> <reason>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_kline.h b/include/commands/cmd_kline.h index 22d04b558..053b7634d 100644 --- a/include/commands/cmd_kline.h +++ b/include/commands/cmd_kline.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_KLINE_H__
#define __CMD_KLINE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /KLINE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_kline : public command_t
{
public:
/** Constructor for kline.
*/
cmd_kline (InspIRCd* Instance) : command_t(Instance,"KLINE",'o',1) { syntax = "<ident@host> [<duration> :<reason>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_KLINE_H__ +#define __CMD_KLINE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /KLINE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_kline : public command_t +{ + public: + /** Constructor for kline. + */ + cmd_kline (InspIRCd* Instance) : command_t(Instance,"KLINE",'o',1) { syntax = "<ident@host> [<duration> :<reason>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_links.h b/include/commands/cmd_links.h index c0748ec7b..7d0eee9e5 100644 --- a/include/commands/cmd_links.h +++ b/include/commands/cmd_links.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_LINKS_H__
#define __CMD_LINKS_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /LINKS. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_links : public command_t
{
public:
/** Constructor for links.
*/
cmd_links (InspIRCd* Instance) : command_t(Instance,"LINKS",0,0) { }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_LINKS_H__ +#define __CMD_LINKS_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /LINKS. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_links : public command_t +{ + public: + /** Constructor for links. + */ + cmd_links (InspIRCd* Instance) : command_t(Instance,"LINKS",0,0) { } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_list.h b/include/commands/cmd_list.h index 01b330bd1..5c956863d 100644 --- a/include/commands/cmd_list.h +++ b/include/commands/cmd_list.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_LIST_H__
#define __CMD_LIST_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /LIST. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_list : public command_t
{
public:
/** Constructor for list.
*/
cmd_list (InspIRCd* Instance) : command_t(Instance,"LIST",0,0) { }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_LIST_H__ +#define __CMD_LIST_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /LIST. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_list : public command_t +{ + public: + /** Constructor for list. + */ + cmd_list (InspIRCd* Instance) : command_t(Instance,"LIST",0,0) { } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_loadmodule.h b/include/commands/cmd_loadmodule.h index e35fc5067..40ca03e81 100644 --- a/include/commands/cmd_loadmodule.h +++ b/include/commands/cmd_loadmodule.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_LOADMODULE_H__
#define __CMD_LOADMODULE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /LOADMODULE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_loadmodule : public command_t
{
public:
/** Constructor for loadmodule.
*/
cmd_loadmodule (InspIRCd* Instance) : command_t(Instance,"LOADMODULE",'o',1) { syntax = "<modulename>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_LOADMODULE_H__ +#define __CMD_LOADMODULE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /LOADMODULE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_loadmodule : public command_t +{ + public: + /** Constructor for loadmodule. + */ + cmd_loadmodule (InspIRCd* Instance) : command_t(Instance,"LOADMODULE",'o',1) { syntax = "<modulename>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_lusers.h b/include/commands/cmd_lusers.h index 3621fcb11..8f9226b4e 100644 --- a/include/commands/cmd_lusers.h +++ b/include/commands/cmd_lusers.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_LUSERS_H__
#define __CMD_LUSERS_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /LUSERS. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_lusers : public command_t
{
public:
/** Constructor for lusers.
*/
cmd_lusers (InspIRCd* Instance) : command_t(Instance,"LUSERS",0,0) { }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_LUSERS_H__ +#define __CMD_LUSERS_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /LUSERS. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_lusers : public command_t +{ + public: + /** Constructor for lusers. + */ + cmd_lusers (InspIRCd* Instance) : command_t(Instance,"LUSERS",0,0) { } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_map.h b/include/commands/cmd_map.h index e67e09b53..f1b586c9f 100644 --- a/include/commands/cmd_map.h +++ b/include/commands/cmd_map.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_MAP_H__
#define __CMD_MAP_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /MAP. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_map : public command_t
{
public:
/** Constructor for map.
*/
cmd_map (InspIRCd* Instance) : command_t(Instance,"MAP",0,0) { }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_MAP_H__ +#define __CMD_MAP_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /MAP. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_map : public command_t +{ + public: + /** Constructor for map. + */ + cmd_map (InspIRCd* Instance) : command_t(Instance,"MAP",0,0) { } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_mode.h b/include/commands/cmd_mode.h index a75bd8635..36e76bf66 100644 --- a/include/commands/cmd_mode.h +++ b/include/commands/cmd_mode.h @@ -1 +1,44 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_ADMIN_H__
#define __CMD_ADMIN_H__
#include "users.h"
#include "channels.h"
#include "ctables.h"
/** Handle /MODE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_mode : public command_t
{
public:
/** Constructor for mode.
*/
cmd_mode (InspIRCd* Instance) : command_t(Instance,"MODE",0,1) { syntax = "<target> <modes> {<mode-parameters>}"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_ADMIN_H__ +#define __CMD_ADMIN_H__ + +#include "users.h" +#include "channels.h" +#include "ctables.h" + +/** Handle /MODE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_mode : public command_t +{ + public: + /** Constructor for mode. + */ + cmd_mode (InspIRCd* Instance) : command_t(Instance,"MODE",0,1) { syntax = "<target> <modes> {<mode-parameters>}"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_modules.h b/include/commands/cmd_modules.h index 02ada014a..372a87c05 100644 --- a/include/commands/cmd_modules.h +++ b/include/commands/cmd_modules.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_MODULES_H__
#define __CMD_MODULES_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /MODULES. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_modules : public command_t
{
public:
/** Constructor for modules.
*/
cmd_modules (InspIRCd* Instance) : command_t(Instance,"MODULES",0,0) { syntax = "[debug]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_MODULES_H__ +#define __CMD_MODULES_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /MODULES. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_modules : public command_t +{ + public: + /** Constructor for modules. + */ + cmd_modules (InspIRCd* Instance) : command_t(Instance,"MODULES",0,0) { syntax = "[debug]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_motd.h b/include/commands/cmd_motd.h index 47c1ca987..75162274a 100644 --- a/include/commands/cmd_motd.h +++ b/include/commands/cmd_motd.h @@ -1 +1,48 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_MOTD_H__
#define __CMD_MOTD_H__
// include the common header files
#include <string>
#include <vector>
#include "inspircd.h"
#include "users.h"
#include "channels.h"
/** Handle /MOTD. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_motd : public command_t
{
public:
/** Constructor for motd.
*/
cmd_motd (InspIRCd* Instance) : command_t(Instance,"MOTD",0,0) { syntax = "[<servername>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_MOTD_H__ +#define __CMD_MOTD_H__ + +// include the common header files + +#include <string> +#include <vector> +#include "inspircd.h" +#include "users.h" +#include "channels.h" + +/** Handle /MOTD. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_motd : public command_t +{ + public: + /** Constructor for motd. + */ + cmd_motd (InspIRCd* Instance) : command_t(Instance,"MOTD",0,0) { syntax = "[<servername>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_names.h b/include/commands/cmd_names.h index b1e78df3f..135e7946b 100644 --- a/include/commands/cmd_names.h +++ b/include/commands/cmd_names.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_NAMES_H__
#define __CMD_NAMES_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /NAMES. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_names : public command_t
{
public:
/** Constructor for names.
*/
cmd_names (InspIRCd* Instance) : command_t(Instance,"NAMES",0,0) { syntax = "{<channel>{,<channel>}}"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_NAMES_H__ +#define __CMD_NAMES_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /NAMES. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_names : public command_t +{ + public: + /** Constructor for names. + */ + cmd_names (InspIRCd* Instance) : command_t(Instance,"NAMES",0,0) { syntax = "{<channel>{,<channel>}}"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_nick.h b/include/commands/cmd_nick.h index b1485a27b..69df1514e 100644 --- a/include/commands/cmd_nick.h +++ b/include/commands/cmd_nick.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_NICK_H__
#define __CMD_NICK_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /NICK. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_nick : public command_t
{
public:
/** Constructor for nick.
*/
cmd_nick (InspIRCd* Instance) : command_t(Instance,"NICK",0,1,true) { syntax = "<newnick>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_NICK_H__ +#define __CMD_NICK_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /NICK. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_nick : public command_t +{ + public: + /** Constructor for nick. + */ + cmd_nick (InspIRCd* Instance) : command_t(Instance,"NICK",0,1,true) { syntax = "<newnick>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_notice.h b/include/commands/cmd_notice.h index 402f4b3b1..ec4372066 100644 --- a/include/commands/cmd_notice.h +++ b/include/commands/cmd_notice.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_NOTICE_H__
#define __CMD_NOTICE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /NOTICE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_notice : public command_t
{
public:
/** Constructor for notice.
*/
cmd_notice (InspIRCd* Instance) : command_t(Instance,"NOTICE",0,2) { syntax = "<target>{,<target>} <message>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_NOTICE_H__ +#define __CMD_NOTICE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /NOTICE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_notice : public command_t +{ + public: + /** Constructor for notice. + */ + cmd_notice (InspIRCd* Instance) : command_t(Instance,"NOTICE",0,2) { syntax = "<target>{,<target>} <message>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_oper.h b/include/commands/cmd_oper.h index 0bfda174e..77c4b0125 100644 --- a/include/commands/cmd_oper.h +++ b/include/commands/cmd_oper.h @@ -1 +1,47 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_OPER_H__
#define __CMD_OPER_H__
// include the common header files
#include "users.h"
#include "channels.h"
bool OneOfMatches(const char* host, const char* ip, const char* hostlist);
/** Handle /OPER. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_oper : public command_t
{
public:
/** Constructor for oper.
*/
cmd_oper (InspIRCd* Instance) : command_t(Instance,"OPER",0,2) { syntax = "<username> <password>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_OPER_H__ +#define __CMD_OPER_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +bool OneOfMatches(const char* host, const char* ip, const char* hostlist); + +/** Handle /OPER. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_oper : public command_t +{ + public: + /** Constructor for oper. + */ + cmd_oper (InspIRCd* Instance) : command_t(Instance,"OPER",0,2) { syntax = "<username> <password>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_part.h b/include/commands/cmd_part.h index e4ce48e08..5f5781874 100644 --- a/include/commands/cmd_part.h +++ b/include/commands/cmd_part.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_PART_H__
#define __CMD_PART_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /PART. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_part : public command_t
{
public:
/** Constructor for part.
*/
cmd_part (InspIRCd* Instance) : command_t(Instance,"PART",0,1) { syntax = "<channel>{,<channel>} [<reason>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_PART_H__ +#define __CMD_PART_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /PART. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_part : public command_t +{ + public: + /** Constructor for part. + */ + cmd_part (InspIRCd* Instance) : command_t(Instance,"PART",0,1) { syntax = "<channel>{,<channel>} [<reason>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_pass.h b/include/commands/cmd_pass.h index d3d2cb76b..53addf80f 100644 --- a/include/commands/cmd_pass.h +++ b/include/commands/cmd_pass.h @@ -1 +1,48 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_PASS_H__
#define __CMD_PASS_H__
// include the common header files
#include <string>
#include <vector>
#include "inspircd.h"
#include "users.h"
#include "channels.h"
/** Handle /PASS. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_pass : public command_t
{
public:
/** Constructor for pass.
*/
cmd_pass (InspIRCd* Instance) : command_t(Instance,"PASS",0,1,true) { syntax = "<password>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_PASS_H__ +#define __CMD_PASS_H__ + +// include the common header files + +#include <string> +#include <vector> +#include "inspircd.h" +#include "users.h" +#include "channels.h" + +/** Handle /PASS. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_pass : public command_t +{ + public: + /** Constructor for pass. + */ + cmd_pass (InspIRCd* Instance) : command_t(Instance,"PASS",0,1,true) { syntax = "<password>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_ping.h b/include/commands/cmd_ping.h index 1e04eb18e..c5350eba5 100644 --- a/include/commands/cmd_ping.h +++ b/include/commands/cmd_ping.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_PING_H__
#define __CMD_PING_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /PING. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_ping : public command_t
{
public:
/** Constructor for ping.
*/
cmd_ping (InspIRCd* Instance) : command_t(Instance,"PING",0,1) { syntax = "<servername> [:<servername>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_PING_H__ +#define __CMD_PING_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /PING. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_ping : public command_t +{ + public: + /** Constructor for ping. + */ + cmd_ping (InspIRCd* Instance) : command_t(Instance,"PING",0,1) { syntax = "<servername> [:<servername>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_pong.h b/include/commands/cmd_pong.h index 73784b340..724ed0dfc 100644 --- a/include/commands/cmd_pong.h +++ b/include/commands/cmd_pong.h @@ -1 +1,46 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_PONG_H__
#define __CMD_PONG_H__
// include the common header files
#include "inspircd.h"
#include "users.h"
#include "channels.h"
/** Handle /PONG. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_pong : public command_t
{
public:
/** Constructor for pong.
*/
cmd_pong (InspIRCd* Instance) : command_t(Instance,"PONG",0,1) { syntax = "<ping-text>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_PONG_H__ +#define __CMD_PONG_H__ + +// include the common header files + +#include "inspircd.h" +#include "users.h" +#include "channels.h" + +/** Handle /PONG. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_pong : public command_t +{ + public: + /** Constructor for pong. + */ + cmd_pong (InspIRCd* Instance) : command_t(Instance,"PONG",0,1) { syntax = "<ping-text>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_privmsg.h b/include/commands/cmd_privmsg.h index 0b43d803c..17b7b0445 100644 --- a/include/commands/cmd_privmsg.h +++ b/include/commands/cmd_privmsg.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_PRIVMSG_H__
#define __CMD_PRIVMSG_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /PRIVMSG. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_privmsg : public command_t
{
public:
/** Constructor for privmsg.
*/
cmd_privmsg (InspIRCd* Instance) : command_t(Instance,"PRIVMSG",0,2) { syntax = "<target>{,<target>} <message>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_PRIVMSG_H__ +#define __CMD_PRIVMSG_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /PRIVMSG. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_privmsg : public command_t +{ + public: + /** Constructor for privmsg. + */ + cmd_privmsg (InspIRCd* Instance) : command_t(Instance,"PRIVMSG",0,2) { syntax = "<target>{,<target>} <message>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_qline.h b/include/commands/cmd_qline.h index 1aca556a8..5d69f9a9a 100644 --- a/include/commands/cmd_qline.h +++ b/include/commands/cmd_qline.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_QLINE_H__
#define __CMD_QLINE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /QLINE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_qline : public command_t
{
public:
/** Constructor for qline.
*/
cmd_qline (InspIRCd* Instance) : command_t(Instance,"QLINE",'o',1) { syntax = "<nick> [<duration> :<reason>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_QLINE_H__ +#define __CMD_QLINE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /QLINE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_qline : public command_t +{ + public: + /** Constructor for qline. + */ + cmd_qline (InspIRCd* Instance) : command_t(Instance,"QLINE",'o',1) { syntax = "<nick> [<duration> :<reason>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_quit.h b/include/commands/cmd_quit.h index 2d3287d13..9c80130a2 100644 --- a/include/commands/cmd_quit.h +++ b/include/commands/cmd_quit.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_QUIT_H__
#define __CMD_QUIT_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /QUIT. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_quit : public command_t
{
public:
/** Constructor for quit.
*/
cmd_quit (InspIRCd* Instance) : command_t(Instance,"QUIT",0,0,true) { syntax = "[<message>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_QUIT_H__ +#define __CMD_QUIT_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /QUIT. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_quit : public command_t +{ + public: + /** Constructor for quit. + */ + cmd_quit (InspIRCd* Instance) : command_t(Instance,"QUIT",0,0,true) { syntax = "[<message>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_rehash.h b/include/commands/cmd_rehash.h index de8d9b6c6..f33ac141d 100644 --- a/include/commands/cmd_rehash.h +++ b/include/commands/cmd_rehash.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_REHASH_H__
#define __CMD_REHASH_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /REHASH. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_rehash : public command_t
{
public:
/** Constructor for rehash.
*/
cmd_rehash (InspIRCd* Instance) : command_t(Instance,"REHASH",'o',0) { syntax = "[<servermask>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_REHASH_H__ +#define __CMD_REHASH_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /REHASH. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_rehash : public command_t +{ + public: + /** Constructor for rehash. + */ + cmd_rehash (InspIRCd* Instance) : command_t(Instance,"REHASH",'o',0) { syntax = "[<servermask>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_reloadmodule.h b/include/commands/cmd_reloadmodule.h index 115ad5b19..76bc656f8 100644 --- a/include/commands/cmd_reloadmodule.h +++ b/include/commands/cmd_reloadmodule.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_RELOADMODULE_H__
#define __CMD_RELOADMODULE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /RELOADMODULE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_reloadmodule : public command_t
{
public:
/** Constructor for reloadmodule.
*/
cmd_reloadmodule (InspIRCd* Instance) : command_t(Instance,"RELOADMODULE",'o',1) { syntax = "<modulename>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_RELOADMODULE_H__ +#define __CMD_RELOADMODULE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /RELOADMODULE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_reloadmodule : public command_t +{ + public: + /** Constructor for reloadmodule. + */ + cmd_reloadmodule (InspIRCd* Instance) : command_t(Instance,"RELOADMODULE",'o',1) { syntax = "<modulename>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_restart.h b/include/commands/cmd_restart.h index c227304aa..89a217a95 100644 --- a/include/commands/cmd_restart.h +++ b/include/commands/cmd_restart.h @@ -1 +1,48 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_RESTART_H__
#define __CMD_RESTART_H__
// include the common header files
#include <string>
#include <deque>
#include <vector>
#include "users.h"
#include "channels.h"
/** Handle /RESTART. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_restart : public command_t
{
public:
/** Constructor for restart.
*/
cmd_restart (InspIRCd* Instance) : command_t(Instance,"RESTART",'o',1) { syntax = "<password>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_RESTART_H__ +#define __CMD_RESTART_H__ + +// include the common header files + +#include <string> +#include <deque> +#include <vector> +#include "users.h" +#include "channels.h" + +/** Handle /RESTART. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_restart : public command_t +{ + public: + /** Constructor for restart. + */ + cmd_restart (InspIRCd* Instance) : command_t(Instance,"RESTART",'o',1) { syntax = "<password>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_rules.h b/include/commands/cmd_rules.h index 2ade369ca..ffa7ea8bd 100644 --- a/include/commands/cmd_rules.h +++ b/include/commands/cmd_rules.h @@ -1 +1,48 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_RULES_H__
#define __CMD_RULES_H__
// include the common header files
#include <string>
#include <vector>
#include "inspircd.h"
#include "users.h"
#include "channels.h"
/** Handle /RULES. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_rules : public command_t
{
public:
/** Constructor for rules.
*/
cmd_rules (InspIRCd* Instance) : command_t(Instance,"RULES",0,0) { syntax = "[<servername>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_RULES_H__ +#define __CMD_RULES_H__ + +// include the common header files + +#include <string> +#include <vector> +#include "inspircd.h" +#include "users.h" +#include "channels.h" + +/** Handle /RULES. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_rules : public command_t +{ + public: + /** Constructor for rules. + */ + cmd_rules (InspIRCd* Instance) : command_t(Instance,"RULES",0,0) { syntax = "[<servername>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_server.h b/include/commands/cmd_server.h index 92867ba6c..3c88c0ac6 100644 --- a/include/commands/cmd_server.h +++ b/include/commands/cmd_server.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_SERVER_H__
#define __CMD_SERVER_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /SERVER. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_server : public command_t
{
public:
/** Constructor for server.
*/
cmd_server (InspIRCd* Instance) : command_t(Instance,"SERVER",0,0) { }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_SERVER_H__ +#define __CMD_SERVER_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /SERVER. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_server : public command_t +{ + public: + /** Constructor for server. + */ + cmd_server (InspIRCd* Instance) : command_t(Instance,"SERVER",0,0) { } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_squit.h b/include/commands/cmd_squit.h index e5e20bbca..43cb115f7 100644 --- a/include/commands/cmd_squit.h +++ b/include/commands/cmd_squit.h @@ -1 +1,48 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_SQUIT_H__
#define __CMD_SQUIT_H__
// include the common header files
#include <string>
#include <vector>
#include "inspircd.h"
#include "users.h"
#include "channels.h"
/** Handle /SQUIT. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_squit : public command_t
{
public:
/** Constructor for squit.
*/
cmd_squit (InspIRCd* Instance) : command_t(Instance,"SQUIT",'o',1) { syntax = "<servername> [<reason>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_SQUIT_H__ +#define __CMD_SQUIT_H__ + +// include the common header files + +#include <string> +#include <vector> +#include "inspircd.h" +#include "users.h" +#include "channels.h" + +/** Handle /SQUIT. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_squit : public command_t +{ + public: + /** Constructor for squit. + */ + cmd_squit (InspIRCd* Instance) : command_t(Instance,"SQUIT",'o',1) { syntax = "<servername> [<reason>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_stats.h b/include/commands/cmd_stats.h index e2aabef2f..b4c0c3784 100644 --- a/include/commands/cmd_stats.h +++ b/include/commands/cmd_stats.h @@ -1 +1,48 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_STATS_H__
#define __CMD_STATS_H__
// include the common header files
#include "inspircd.h"
#include "users.h"
#include "channels.h"
DllExport void DoStats(InspIRCd* Instance, char statschar, userrec* user, string_list &results);
/** Handle /STATS. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_stats : public command_t
{
public:
/** Constructor for stats.
*/
cmd_stats (InspIRCd* Instance) : command_t(Instance,"STATS",0,1) { syntax = "<stats-symbol> [<servername>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_STATS_H__ +#define __CMD_STATS_H__ + +// include the common header files + +#include "inspircd.h" +#include "users.h" +#include "channels.h" + +DllExport void DoStats(InspIRCd* Instance, char statschar, userrec* user, string_list &results); + +/** Handle /STATS. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_stats : public command_t +{ + public: + /** Constructor for stats. + */ + cmd_stats (InspIRCd* Instance) : command_t(Instance,"STATS",0,1) { syntax = "<stats-symbol> [<servername>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_summon.h b/include/commands/cmd_summon.h index 18e0871ab..717863f35 100644 --- a/include/commands/cmd_summon.h +++ b/include/commands/cmd_summon.h @@ -1 +1,48 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_SUMMON_H__
#define __CMD_SUMMON_H__
// include the common header files
#include <string>
#include <vector>
#include "inspircd.h"
#include "users.h"
#include "channels.h"
/** Handle /SUMMON stub. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_summon : public command_t
{
public:
/** Constructor for summon.
*/
cmd_summon (InspIRCd* Instance) : command_t(Instance,"SUMMON",0,0) { }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_SUMMON_H__ +#define __CMD_SUMMON_H__ + +// include the common header files + +#include <string> +#include <vector> +#include "inspircd.h" +#include "users.h" +#include "channels.h" + +/** Handle /SUMMON stub. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_summon : public command_t +{ + public: + /** Constructor for summon. + */ + cmd_summon (InspIRCd* Instance) : command_t(Instance,"SUMMON",0,0) { } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_time.h b/include/commands/cmd_time.h index 395281a50..0a2dc2f95 100644 --- a/include/commands/cmd_time.h +++ b/include/commands/cmd_time.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_TIME_H__
#define __CMD_TIME_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /TIME. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_time : public command_t
{
public:
/** Constructor for time.
*/
cmd_time (InspIRCd* Instance) : command_t(Instance,"TIME",0,0) { syntax = "[<servername>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_TIME_H__ +#define __CMD_TIME_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /TIME. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_time : public command_t +{ + public: + /** Constructor for time. + */ + cmd_time (InspIRCd* Instance) : command_t(Instance,"TIME",0,0) { syntax = "[<servername>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_topic.h b/include/commands/cmd_topic.h index 05ecd7599..c3ac113ef 100644 --- a/include/commands/cmd_topic.h +++ b/include/commands/cmd_topic.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_TOPIC_H__
#define __CMD_TOPIC_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /TOPIC. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_topic : public command_t
{
public:
/** Constructor for topic.
*/
cmd_topic (InspIRCd* Instance) : command_t(Instance,"TOPIC",0,1) { syntax = "<channel> [<topic>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_TOPIC_H__ +#define __CMD_TOPIC_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /TOPIC. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_topic : public command_t +{ + public: + /** Constructor for topic. + */ + cmd_topic (InspIRCd* Instance) : command_t(Instance,"TOPIC",0,1) { syntax = "<channel> [<topic>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_trace.h b/include/commands/cmd_trace.h index f9f8f2bb8..2c681363d 100644 --- a/include/commands/cmd_trace.h +++ b/include/commands/cmd_trace.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_TRACE_H__
#define __CMD_TRACE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /TRACE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_trace : public command_t
{
public:
/** Constructor for trace.
*/
cmd_trace (InspIRCd* Instance) : command_t(Instance,"TRACE",'o',0) { syntax = "[<object>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_TRACE_H__ +#define __CMD_TRACE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /TRACE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_trace : public command_t +{ + public: + /** Constructor for trace. + */ + cmd_trace (InspIRCd* Instance) : command_t(Instance,"TRACE",'o',0) { syntax = "[<object>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_unloadmodule.h b/include/commands/cmd_unloadmodule.h index b8e87e713..2f435576f 100644 --- a/include/commands/cmd_unloadmodule.h +++ b/include/commands/cmd_unloadmodule.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_UNLOADMODULE_H__
#define __CMD_UNLOADMODULE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /UNLOADMODULE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_unloadmodule : public command_t
{
public:
/** Constructor for unloadmodule.
*/
cmd_unloadmodule (InspIRCd* Instance) : command_t(Instance,"UNLOADMODULE",'o',1) { syntax = "<modulename>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_UNLOADMODULE_H__ +#define __CMD_UNLOADMODULE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /UNLOADMODULE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_unloadmodule : public command_t +{ + public: + /** Constructor for unloadmodule. + */ + cmd_unloadmodule (InspIRCd* Instance) : command_t(Instance,"UNLOADMODULE",'o',1) { syntax = "<modulename>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_user.h b/include/commands/cmd_user.h index d31484f06..eb835e290 100644 --- a/include/commands/cmd_user.h +++ b/include/commands/cmd_user.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_USER_H__
#define __CMD_USER_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /USER. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_user : public command_t
{
public:
/** Constructor for user.
*/
cmd_user (InspIRCd* Instance) : command_t(Instance,"USER",0,4,true) { syntax = "<username> <localhost> <remotehost> <GECOS>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_USER_H__ +#define __CMD_USER_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /USER. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_user : public command_t +{ + public: + /** Constructor for user. + */ + cmd_user (InspIRCd* Instance) : command_t(Instance,"USER",0,4,true) { syntax = "<username> <localhost> <remotehost> <GECOS>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_userhost.h b/include/commands/cmd_userhost.h index 374025745..0a72bcda2 100644 --- a/include/commands/cmd_userhost.h +++ b/include/commands/cmd_userhost.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_USERHOST_H__
#define __CMD_USERHOST_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /USERHOST. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_userhost : public command_t
{
public:
/** Constructor for userhost.
*/
cmd_userhost (InspIRCd* Instance) : command_t(Instance,"USERHOST",0,1) { syntax = "<nick>{,<nick>}"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_USERHOST_H__ +#define __CMD_USERHOST_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /USERHOST. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_userhost : public command_t +{ + public: + /** Constructor for userhost. + */ + cmd_userhost (InspIRCd* Instance) : command_t(Instance,"USERHOST",0,1) { syntax = "<nick>{,<nick>}"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_users.h b/include/commands/cmd_users.h index 9374c1de2..60341871d 100644 --- a/include/commands/cmd_users.h +++ b/include/commands/cmd_users.h @@ -1 +1,48 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_USERS_H__
#define __CMD_USERS_H__
// include the common header files
//
#include <string>
#include <vector>
#include "inspircd.h"
#include "users.h"
#include "channels.h"
/** Handle /USERS stub. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_users : public command_t
{
public:
/** Constructor for users.
*/
cmd_users (InspIRCd* Instance) : command_t(Instance,"USERS",0,0) { }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_USERS_H__ +#define __CMD_USERS_H__ + +// include the common header files +// +#include <string> +#include <vector> +#include "inspircd.h" +#include "users.h" +#include "channels.h" + +/** Handle /USERS stub. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_users : public command_t +{ + public: + /** Constructor for users. + */ + cmd_users (InspIRCd* Instance) : command_t(Instance,"USERS",0,0) { } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_version.h b/include/commands/cmd_version.h index 9ded1641a..824a9ef7e 100644 --- a/include/commands/cmd_version.h +++ b/include/commands/cmd_version.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_VERSION_H__
#define __CMD_VERSION_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /VERSION. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_version : public command_t
{
public:
/** Constructor for version.
*/
cmd_version (InspIRCd* Instance) : command_t(Instance,"VERSION",0,0) { syntax = "[<servername>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_VERSION_H__ +#define __CMD_VERSION_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /VERSION. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_version : public command_t +{ + public: + /** Constructor for version. + */ + cmd_version (InspIRCd* Instance) : command_t(Instance,"VERSION",0,0) { syntax = "[<servername>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_wallops.h b/include/commands/cmd_wallops.h index 514f6a5de..548ba53de 100644 --- a/include/commands/cmd_wallops.h +++ b/include/commands/cmd_wallops.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_WALLOPS_H__
#define __CMD_WALLOPS_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /WALLOPS. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_wallops : public command_t
{
public:
/** Constructor for wallops.
*/
cmd_wallops (InspIRCd* Instance) : command_t(Instance,"WALLOPS",'o',1) { syntax = "<any-text>"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_WALLOPS_H__ +#define __CMD_WALLOPS_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /WALLOPS. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_wallops : public command_t +{ + public: + /** Constructor for wallops. + */ + cmd_wallops (InspIRCd* Instance) : command_t(Instance,"WALLOPS",'o',1) { syntax = "<any-text>"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_who.h b/include/commands/cmd_who.h index e84de3d35..6ccfa3b5d 100644 --- a/include/commands/cmd_who.h +++ b/include/commands/cmd_who.h @@ -1 +1,59 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_WHO_H__
#define __CMD_WHO_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /WHO. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_who : public command_t
{
bool CanView(chanrec* chan, userrec* user);
bool opt_viewopersonly;
bool opt_showrealhost;
bool opt_unlimit;
bool opt_realname;
bool opt_mode;
bool opt_ident;
bool opt_metadata;
bool opt_port;
bool opt_away;
bool opt_local;
bool opt_far;
public:
/** Constructor for who.
*/
cmd_who (InspIRCd* Instance) : command_t(Instance,"WHO",0,1) { syntax = "<server>|<nickname>|<channel>|<realname>|<host>|0 [ohurmMiaplf]"; }
void SendWhoLine(userrec* user, const std::string &initial, chanrec* ch, userrec* u, std::vector<std::string> &whoresults);
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
bool whomatch(userrec* user, const char* matchtext);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_WHO_H__ +#define __CMD_WHO_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /WHO. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_who : public command_t +{ + bool CanView(chanrec* chan, userrec* user); + bool opt_viewopersonly; + bool opt_showrealhost; + bool opt_unlimit; + bool opt_realname; + bool opt_mode; + bool opt_ident; + bool opt_metadata; + bool opt_port; + bool opt_away; + bool opt_local; + bool opt_far; + public: + /** Constructor for who. + */ + cmd_who (InspIRCd* Instance) : command_t(Instance,"WHO",0,1) { syntax = "<server>|<nickname>|<channel>|<realname>|<host>|0 [ohurmMiaplf]"; } + void SendWhoLine(userrec* user, const std::string &initial, chanrec* ch, userrec* u, std::vector<std::string> &whoresults); + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); + bool whomatch(userrec* user, const char* matchtext); +}; + +#endif diff --git a/include/commands/cmd_whois.h b/include/commands/cmd_whois.h index 5e0c0d4d3..d3086788a 100644 --- a/include/commands/cmd_whois.h +++ b/include/commands/cmd_whois.h @@ -1 +1,48 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_WHOIS_H__
#define __CMD_WHOIS_H__
// include the common header files
#include "users.h"
#include "channels.h"
const char* Spacify(char* n);
DllExport void do_whois(InspIRCd* Instance, userrec* user, userrec* dest,unsigned long signon, unsigned long idle, const char* nick);
/** Handle /WHOIS. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_whois : public command_t
{
public:
/** Constructor for whois.
*/
cmd_whois (InspIRCd* Instance) : command_t(Instance,"WHOIS",0,1) { syntax = "<nick>{,<nick>}"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_WHOIS_H__ +#define __CMD_WHOIS_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +const char* Spacify(char* n); +DllExport void do_whois(InspIRCd* Instance, userrec* user, userrec* dest,unsigned long signon, unsigned long idle, const char* nick); + +/** Handle /WHOIS. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_whois : public command_t +{ + public: + /** Constructor for whois. + */ + cmd_whois (InspIRCd* Instance) : command_t(Instance,"WHOIS",0,1) { syntax = "<nick>{,<nick>}"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/commands/cmd_whowas.h b/include/commands/cmd_whowas.h index bf020143c..58aa14bfd 100644 --- a/include/commands/cmd_whowas.h +++ b/include/commands/cmd_whowas.h @@ -1 +1,144 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_WHOWAS_H__
#define __CMD_WHOWAS_H__
// include the common header files
#include "users.h"
#include "channels.h"
/* list of available internal commands */
enum Internals
{
WHOWAS_ADD = 1,
WHOWAS_STATS = 2,
WHOWAS_PRUNE = 3,
WHOWAS_MAINTAIN = 4
};
/* Forward ref for timer */
class WhoWasMaintainTimer;
/* Forward ref for typedefs */
class WhoWasGroup;
/** InspTimer that is used to maintain the whowas list, called once an hour
*/
extern WhoWasMaintainTimer* timer;
/** A group of users related by nickname
*/
typedef std::deque<WhoWasGroup*> whowas_set;
/** Sets of users in the whowas system
*/
typedef std::map<irc::string,whowas_set*> whowas_users;
/** Sets of time and users in whowas list
*/
typedef std::deque<std::pair<time_t,irc::string> > whowas_users_fifo;
/** Handle /WHOWAS. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_whowas : public command_t
{
private:
/** Whowas container, contains a map of vectors of users tracked by WHOWAS
*/
whowas_users whowas;
/** Whowas container, contains a map of time_t to users tracked by WHOWAS
*/
whowas_users_fifo whowas_fifo;
/* String holding stats so it can be collected
*/
std::string stats;
public:
cmd_whowas(InspIRCd* Instance);
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult HandleInternal(const unsigned int id, const std::deque<classbase*> ¶meters);
void AddToWhoWas(userrec* user);
void GetStats(Extensible* ext);
void PruneWhoWas(time_t t);
void MaintainWhoWas(time_t t);
virtual ~cmd_whowas();
};
/** Used to hold WHOWAS information
*/
class WhoWasGroup : public classbase
{
public:
/** Real host
*/
char* host;
/** Displayed host
*/
char* dhost;
/** Ident
*/
char* ident;
/** Server name
*/
const char* server;
/** Fullname (GECOS)
*/
char* gecos;
/** Signon time
*/
time_t signon;
/** Initialize this WhoQasFroup with a user
*/
WhoWasGroup(userrec* user);
/** Destructor
*/
~WhoWasGroup();
};
class WhoWasMaintainTimer : public InspTimer
{
private:
InspIRCd* ServerInstance;
public:
WhoWasMaintainTimer(InspIRCd* Instance, long interval)
: InspTimer(interval, Instance->Time(), true), ServerInstance(Instance)
{
}
virtual void Tick(time_t TIME);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_WHOWAS_H__ +#define __CMD_WHOWAS_H__ + + +// include the common header files + +#include "users.h" +#include "channels.h" + +/* list of available internal commands */ +enum Internals +{ + WHOWAS_ADD = 1, + WHOWAS_STATS = 2, + WHOWAS_PRUNE = 3, + WHOWAS_MAINTAIN = 4 +}; + +/* Forward ref for timer */ +class WhoWasMaintainTimer; + +/* Forward ref for typedefs */ +class WhoWasGroup; + +/** InspTimer that is used to maintain the whowas list, called once an hour + */ +extern WhoWasMaintainTimer* timer; + +/** A group of users related by nickname + */ +typedef std::deque<WhoWasGroup*> whowas_set; + +/** Sets of users in the whowas system + */ +typedef std::map<irc::string,whowas_set*> whowas_users; + +/** Sets of time and users in whowas list + */ +typedef std::deque<std::pair<time_t,irc::string> > whowas_users_fifo; + +/** Handle /WHOWAS. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_whowas : public command_t +{ + private: + /** Whowas container, contains a map of vectors of users tracked by WHOWAS + */ + whowas_users whowas; + + /** Whowas container, contains a map of time_t to users tracked by WHOWAS + */ + whowas_users_fifo whowas_fifo; + + /* String holding stats so it can be collected + */ + std::string stats; + + public: + cmd_whowas(InspIRCd* Instance); + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult HandleInternal(const unsigned int id, const std::deque<classbase*> ¶meters); + void AddToWhoWas(userrec* user); + void GetStats(Extensible* ext); + void PruneWhoWas(time_t t); + void MaintainWhoWas(time_t t); + virtual ~cmd_whowas(); +}; + +/** Used to hold WHOWAS information + */ +class WhoWasGroup : public classbase +{ + public: + /** Real host + */ + char* host; + /** Displayed host + */ + char* dhost; + /** Ident + */ + char* ident; + /** Server name + */ + const char* server; + /** Fullname (GECOS) + */ + char* gecos; + /** Signon time + */ + time_t signon; + + /** Initialize this WhoQasFroup with a user + */ + WhoWasGroup(userrec* user); + /** Destructor + */ + ~WhoWasGroup(); +}; + +class WhoWasMaintainTimer : public InspTimer +{ + private: + InspIRCd* ServerInstance; + public: + WhoWasMaintainTimer(InspIRCd* Instance, long interval) + : InspTimer(interval, Instance->Time(), true), ServerInstance(Instance) + { + } + virtual void Tick(time_t TIME); +}; + +#endif diff --git a/include/commands/cmd_zline.h b/include/commands/cmd_zline.h index acd7f2ffd..cf9edbfc6 100644 --- a/include/commands/cmd_zline.h +++ b/include/commands/cmd_zline.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __CMD_ZLINE_H__
#define __CMD_ZLINE_H__
// include the common header files
#include "users.h"
#include "channels.h"
/** Handle /ZLINE. These command handlers can be reloaded by the core,
* and handle basic RFC1459 commands. Commands within modules work
* the same way, however, they can be fully unloaded, where these
* may not.
*/
class cmd_zline : public command_t
{
public:
/** Constructor for zline.
*/
cmd_zline (InspIRCd* Instance) : command_t(Instance,"ZLINE",'o',1) { syntax = "<ipmask> [<duration> :<reason>]"; }
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
CmdResult Handle(const char** parameters, int pcnt, userrec *user);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd is copyright (C) 2002-2007 ChatSpike-Dev. + * E-mail: + * <brain@chatspike.net> + * <Craig@chatspike.net> + * + * Written by Craig Edwards, Craig McLure, and others. + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#ifndef __CMD_ZLINE_H__ +#define __CMD_ZLINE_H__ + +// include the common header files + +#include "users.h" +#include "channels.h" + +/** Handle /ZLINE. These command handlers can be reloaded by the core, + * and handle basic RFC1459 commands. Commands within modules work + * the same way, however, they can be fully unloaded, where these + * may not. + */ +class cmd_zline : public command_t +{ + public: + /** Constructor for zline. + */ + cmd_zline (InspIRCd* Instance) : command_t(Instance,"ZLINE",'o',1) { syntax = "<ipmask> [<duration> :<reason>]"; } + /** Handle command. + * @param parameters The parameters to the comamnd + * @param pcnt The number of parameters passed to teh command + * @param user The user issuing the command + * @return A value from CmdResult to indicate command success or failure. + */ + CmdResult Handle(const char** parameters, int pcnt, userrec *user); +}; + +#endif diff --git a/include/configreader.h b/include/configreader.h index 687ca4d8d..8a719f77e 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -1 +1,790 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef INSPIRCD_CONFIGREADER
#define INSPIRCD_CONFIGREADER
/* handy defines */
/** Determines if a channel op is exempt from given mode m,
* in config of server instance s.
*/
#define CHANOPS_EXEMPT(s, m) (s->Config->ExemptChanOps[(unsigned char)m])
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include "inspircd.h"
#include "globals.h"
#include "modules.h"
#include "socketengine.h"
#include "socket.h"
/* Required forward definitions */
class ServerConfig;
class InspIRCd;
class InspSocket;
/** Types of data in the core config
*/
enum ConfigDataType
{
DT_NOTHING = 0, /* No data */
DT_INTEGER = 1, /* Integer */
DT_CHARPTR = 2, /* Char pointer */
DT_BOOLEAN = 3, /* Boolean */
DT_ALLOW_NEWLINE = 128 /* New line characters allowed */
};
/** Holds a config value, either string, integer or boolean.
* Callback functions receive one or more of these, either on
* their own as a reference, or in a reference to a deque of them.
* The callback function can then alter the values of the ValueItem
* classes to validate the settings.
*/
class ValueItem
{
/** Actual data */
std::string v;
public:
/** Initialize with an int */
ValueItem(int value);
/** Initialize with a bool */
ValueItem(bool value);
/** Initialize with a char pointer */
ValueItem(char* value);
/** Change value to a char pointer */
void Set(char* value);
/** Change value to a const char pointer */
void Set(const char* val);
/** Change value to an int */
void Set(int value);
/** Get value as an int */
int GetInteger();
/** Get value as a string */
char* GetString();
/** Get value as a bool */
bool GetBool();
};
/** The base class of the container 'ValueContainer'
* used internally by the core to hold core values.
*/
class ValueContainerBase
{
public:
/** Constructor */
ValueContainerBase() { }
/** Destructor */
virtual ~ValueContainerBase() { }
};
/** ValueContainer is used to contain pointers to different
* core values such as the server name, maximum number of
* clients etc.
* It is specialized to hold a data type, then pointed at
* a value in the ServerConfig class. When the value has been
* read and validated, the Set method is called to write the
* value safely in a type-safe manner.
*/
template<typename T> class ValueContainer : public ValueContainerBase
{
/** Contained item */
T val;
public:
/** Initialize with nothing */
ValueContainer()
{
val = NULL;
}
/** Initialize with a value of type T */
ValueContainer(T Val)
{
val = Val;
}
/** Change value to type T of size s */
void Set(T newval, size_t s)
{
memcpy(val, newval, s);
}
};
/** A specialization of ValueContainer to hold a pointer to a bool
*/
typedef ValueContainer<bool*> ValueContainerBool;
/** A specialization of ValueContainer to hold a pointer to
* an unsigned int
*/
typedef ValueContainer<unsigned int*> ValueContainerUInt;
/** A specialization of ValueContainer to hold a pointer to
* a char array.
*/
typedef ValueContainer<char*> ValueContainerChar;
/** A specialization of ValueContainer to hold a pointer to
* an int
*/
typedef ValueContainer<int*> ValueContainerInt;
/** A set of ValueItems used by multi-value validator functions
*/
typedef std::deque<ValueItem> ValueList;
/** A callback for validating a single value
*/
typedef bool (*Validator)(ServerConfig* conf, const char*, const char*, ValueItem&);
/** A callback for validating multiple value entries
*/
typedef bool (*MultiValidator)(ServerConfig* conf, const char*, char**, ValueList&, int*);
/** A callback indicating the end of a group of entries
*/
typedef bool (*MultiNotify)(ServerConfig* conf, const char*);
/** Holds a core configuration item and its callbacks
*/
struct InitialConfig
{
/** Tag name */
char* tag;
/** Value name */
char* value;
/** Default, if not defined */
char* default_value;
/** Value containers */
ValueContainerBase* val;
/** Data types */
ConfigDataType datatype;
/** Validation function */
Validator validation_function;
};
/** Holds a core configuration item and its callbacks
* where there may be more than one item
*/
struct MultiConfig
{
/** Tag name */
const char* tag;
/** One or more items within tag */
char* items[13];
/** One or more defaults for items within tags */
char* items_default[13];
/** One or more data types */
int datatype[13];
/** Initialization function */
MultiNotify init_function;
/** Validation function */
MultiValidator validation_function;
/** Completion function */
MultiNotify finish_function;
};
/** A set of oper types
*/
typedef std::map<irc::string,char*> opertype_t;
/** A Set of oper classes
*/
typedef std::map<irc::string,char*> operclass_t;
/** This class holds the bulk of the runtime configuration for the ircd.
* It allows for reading new config values, accessing configuration files,
* and storage of the configuration data needed to run the ircd, such as
* the servername, connect classes, /ADMIN data, MOTDs and filenames etc.
*/
class CoreExport ServerConfig : public Extensible
{
private:
/** Creator/owner pointer
*/
InspIRCd* ServerInstance;
/** This variable holds the names of all
* files included from the main one. This
* is used to make sure that no files are
* recursively included.
*/
std::vector<std::string> include_stack;
/** This private method processes one line of
* configutation, appending errors to errorstream
* and setting error if an error has occured.
*/
bool ParseLine(ConfigDataHash &target, std::string &line, long linenumber, std::ostringstream &errorstream);
/** Process an include directive
*/
bool DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream);
/** Check that there is only one of each configuration item
*/
bool CheckOnce(char* tag, bool bail, userrec* user);
public:
InspIRCd* GetInstance();
/** This holds all the information in the config file,
* it's indexed by tag name to a vector of key/values.
*/
ConfigDataHash config_data;
/** Max number of WhoWas entries per user.
*/
int WhoWasGroupSize;
/** Max number of cumulative user-entries in WhoWas.
* When max reached and added to, push out oldest entry FIFO style.
*/
int WhoWasMaxGroups;
/** Max seconds a user is kept in WhoWas before being pruned.
*/
int WhoWasMaxKeep;
/** Holds the server name of the local server
* as defined by the administrator.
*/
char ServerName[MAXBUF];
/** Notice to give to users when they are Xlined
*/
char MoronBanner[MAXBUF];
/* Holds the network name the local server
* belongs to. This is an arbitary field defined
* by the administrator.
*/
char Network[MAXBUF];
/** Holds the description of the local server
* as defined by the administrator.
*/
char ServerDesc[MAXBUF];
/** Holds the admin's name, for output in
* the /ADMIN command.
*/
char AdminName[MAXBUF];
/** Holds the email address of the admin,
* for output in the /ADMIN command.
*/
char AdminEmail[MAXBUF];
/** Holds the admin's nickname, for output
* in the /ADMIN command
*/
char AdminNick[MAXBUF];
/** The admin-configured /DIE password
*/
char diepass[MAXBUF];
/** The admin-configured /RESTART password
*/
char restartpass[MAXBUF];
/** The pathname and filename of the message of the
* day file, as defined by the administrator.
*/
char motd[MAXBUF];
/** The pathname and filename of the rules file,
* as defined by the administrator.
*/
char rules[MAXBUF];
/** The quit prefix in use, or an empty string
*/
char PrefixQuit[MAXBUF];
/** The quit suffix in use, or an empty string
*/
char SuffixQuit[MAXBUF];
/** The fixed quit message in use, or an empty string
*/
char FixedQuit[MAXBUF];
/** The last string found within a <die> tag, or
* an empty string.
*/
char DieValue[MAXBUF];
/** The DNS server to use for DNS queries
*/
char DNSServer[MAXBUF];
/** This variable contains a space-seperated list
* of commands which are disabled by the
* administrator of the server for non-opers.
*/
char DisabledCommands[MAXBUF];
/** The full path to the modules directory.
* This is either set at compile time, or
* overridden in the configuration file via
* the <options> tag.
*/
char ModPath[1024];
/** The full pathname to the executable, as
* given in argv[0] when the program starts.
*/
char MyExecutable[1024];
/** The file handle of the logfile. If this
* value is NULL, the log file is not open,
* probably due to a permissions error on
* startup (this should not happen in normal
* operation!).
*/
FILE *log_file;
/** If this value is true, the owner of the
* server specified -nofork on the command
* line, causing the daemon to stay in the
* foreground.
*/
bool nofork;
/** If this value if true then all log
* messages will be output, regardless of
* the level given in the config file.
* This is set with the -debug commandline
* option.
*/
bool forcedebug;
/** If this is true then log output will be
* written to the logfile. This is the default.
* If you put -nolog on the commandline then
* the logfile will not be written.
* This is meant to be used in conjunction with
* -debug for debugging without filling up the
* hard disk.
*/
bool writelog;
/** If this value is true, halfops have been
* enabled in the configuration file.
*/
bool AllowHalfop;
/** If this is set to true, then mode lists (e.g
* MODE #chan b) are hidden from unprivileged
* users.
*/
bool HideModeLists[256];
/** If this is set to true, then channel operators
* are exempt from this channel mode. Used for +Sc etc.
*/
bool ExemptChanOps[256];
/** The number of seconds the DNS subsystem
* will wait before timing out any request.
*/
int dns_timeout;
/** The size of the read() buffer in the user
* handling code, used to read data into a user's
* recvQ.
*/
int NetBufferSize;
/** The value to be used for listen() backlogs
* as default.
*/
int MaxConn;
/** The soft limit value assigned to the irc server.
* The IRC server will not allow more than this
* number of local users.
*/
unsigned int SoftLimit;
/** Maximum number of targets for a multi target command
* such as PRIVMSG or KICK
*/
unsigned int MaxTargets;
/** The maximum number of /WHO results allowed
* in any single /WHO command.
*/
int MaxWhoResults;
/** True if the DEBUG loglevel is selected.
*/
int debugging;
/** The loglevel in use by the IRC server
*/
int LogLevel;
/** How many seconds to wait before exiting
* the program when /DIE is correctly issued.
*/
int DieDelay;
/** True if we're going to hide netsplits as *.net *.split for non-opers
*/
bool HideSplits;
/** True if we're going to hide ban reasons for non-opers (e.g. G-Lines,
* K-Lines, Z-Lines)
*/
bool HideBans;
/** Announce invites to the channel with a server notice
*/
bool AnnounceInvites;
/** If this is enabled then operators will
* see invisible (+i) channels in /whois.
*/
bool OperSpyWhois;
/** Set to a non-empty string to obfuscate the server name of users in WHOIS
*/
char HideWhoisServer[MAXBUF];
/** Set to a non empty string to obfuscate nicknames prepended to a KILL.
*/
char HideKillsServer[MAXBUF];
/** The MOTD file, cached in a file_cache type.
*/
file_cache MOTD;
/** The RULES file, cached in a file_cache type.
*/
file_cache RULES;
/** The full pathname and filename of the PID
* file as defined in the configuration.
*/
char PID[1024];
/** The connect classes in use by the IRC server.
*/
ClassVector Classes;
/** A list of module names (names only, no paths)
* which are currently loaded by the server.
*/
std::vector<std::string> module_names;
/** A list of the classes for listening client ports
*/
std::vector<ListenSocket*> ports;
/** Boolean sets of which modules implement which functions
*/
char implement_lists[255][255];
/** Global implementation list
*/
char global_implementation[255];
/** A list of ports claimed by IO Modules
*/
std::map<int,Module*> IOHookModule;
std::map<InspSocket*, Module*> SocketIOHookModule;
/** The 005 tokens of this server (ISUPPORT)
* populated/repopulated upon loading or unloading
* modules.
*/
std::string data005;
/** isupport strings
*/
std::vector<std::string> isupport;
/** STATS characters in this list are available
* only to operators.
*/
char UserStats[MAXBUF];
/** The path and filename of the ircd.log file
*/
std::string logpath;
/** Default channel modes
*/
char DefaultModes[MAXBUF];
/** Custom version string, which if defined can replace the system info in VERSION.
*/
char CustomVersion[MAXBUF];
/** List of u-lined servers
*/
std::map<irc::string, bool> ulines;
/** Max banlist sizes for channels (the std::string is a glob)
*/
std::map<std::string, int> maxbans;
/** Directory where the inspircd binary resides
*/
std::string MyDir;
/** If set to true, no user DNS lookups are to be performed
*/
bool NoUserDns;
/** If set to true, provide syntax hints for unknown commands
*/
bool SyntaxHints;
/** If set to true, users appear to quit then rejoin when their hosts change.
* This keeps clients synchronized properly.
*/
bool CycleHosts;
/** If set to true, prefixed channel NOTICEs and PRIVMSGs will have the prefix
* added to the outgoing text for undernet style msg prefixing.
*/
bool UndernetMsgPrefix;
/** If set to true, the full nick!user@host will be shown in the TOPIC command
* for who set the topic last. If false, only the nick is shown.
*/
bool FullHostInTopic;
/** All oper type definitions from the config file
*/
opertype_t opertypes;
/** All oper class definitions from the config file
*/
operclass_t operclass;
/** Saved argv from startup
*/
char** argv;
/** Saved argc from startup
*/
int argc;
/** Max channels per user
*/
unsigned int MaxChans;
/** Oper max channels per user
*/
unsigned int OperMaxChans;
/** Construct a new ServerConfig
*/
ServerConfig(InspIRCd* Instance);
/** Clears the include stack in preperation for a Read() call.
*/
void ClearStack();
/** Update the 005 vector
*/
void Update005();
/** Send the 005 numerics (ISUPPORT) to a user
*/
void Send005(userrec* user);
/** Read the entire configuration into memory
* and initialize this class. All other methods
* should be used only by the core.
*/
void Read(bool bail, userrec* user);
/** Read a file into a file_cache object
*/
bool ReadFile(file_cache &F, const char* fname);
/** Report a configuration error given in errormessage.
* @param bail If this is set to true, the error is sent to the console, and the program exits
* @param user If this is set to a non-null value, and bail is false, the errors are spooled to
* this user as SNOTICEs.
* If the parameter is NULL, the messages are spooled to all users via WriteOpers as SNOTICEs.
*/
void ReportConfigError(const std::string &errormessage, bool bail, userrec* user);
/** Load 'filename' into 'target', with the new config parser everything is parsed into
* tag/key/value at load-time rather than at read-value time.
*/
bool LoadConf(ConfigDataHash &target, const char* filename, std::ostringstream &errorstream);
/** Load 'filename' into 'target', with the new config parser everything is parsed into
* tag/key/value at load-time rather than at read-value time.
*/
bool LoadConf(ConfigDataHash &target, const std::string &filename, std::ostringstream &errorstream);
/* Both these return true if the value existed or false otherwise */
/** Writes 'length' chars into 'result' as a string
*/
bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds = false);
/** Writes 'length' chars into 'result' as a string
*/
bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, char* result, int length, bool allow_linefeeds = false);
/** Writes 'length' chars into 'result' as a string
*/
bool ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, std::string &result, bool allow_linefeeds = false);
/** Writes 'length' chars into 'result' as a string
*/
bool ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, std::string &result, bool allow_linefeeds = false);
/** Tries to convert the value to an integer and write it to 'result'
*/
bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, int index, int &result);
/** Tries to convert the value to an integer and write it to 'result'
*/
bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, int &result);
/** Tries to convert the value to an integer and write it to 'result'
*/
bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, int &result);
/** Tries to convert the value to an integer and write it to 'result'
*/
bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, int &result);
/** Returns true if the value exists and has a true value, false otherwise
*/
bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, int index);
/** Returns true if the value exists and has a true value, false otherwise
*/
bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index);
/** Returns true if the value exists and has a true value, false otherwise
*/
bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, int index);
/** Returns true if the value exists and has a true value, false otherwise
*/
bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index);
/** Returns the number of occurences of tag in the config file
*/
int ConfValueEnum(ConfigDataHash &target, const char* tag);
/** Returns the number of occurences of tag in the config file
*/
int ConfValueEnum(ConfigDataHash &target, const std::string &tag);
/** Returns the numbers of vars inside the index'th 'tag in the config file
*/
int ConfVarEnum(ConfigDataHash &target, const char* tag, int index);
/** Returns the numbers of vars inside the index'th 'tag in the config file
*/
int ConfVarEnum(ConfigDataHash &target, const std::string &tag, int index);
/** Get a pointer to the module which has hooked the given port.
* @parameter port Port number
* @return Returns a pointer to the hooking module, or NULL
*/
Module* GetIOHook(int port);
/** Hook a module to a client port, so that it can receive notifications
* of low-level port activity.
* @param port The port number
* @param Module the module to hook to the port
* @return True if the hook was successful.
*/
bool AddIOHook(int port, Module* iomod);
/** Delete a module hook from a client port.
* @param port The port to detatch from
* @return True if successful
*/
bool DelIOHook(int port);
/** Get a pointer to the module which has hooked the given InspSocket class.
* @parameter port Port number
* @return Returns a pointer to the hooking module, or NULL
*/
Module* GetIOHook(InspSocket* is);
/** Hook a module to an InspSocket class, so that it can receive notifications
* of low-level socket activity.
* @param iomod The module to hook to the socket
* @param is The InspSocket to attach to
* @return True if the hook was successful.
*/
bool AddIOHook(Module* iomod, InspSocket* is);
/** Delete a module hook from an InspSocket.
* @param is The InspSocket to detatch from.
* @return True if the unhook was successful
*/
bool DelIOHook(InspSocket* is);
/** Returns the fully qualified path to the inspircd directory
* @return The full program directory
*/
std::string GetFullProgDir();
/** Returns true if a directory is valid (within the modules directory).
* @param dirandfile The directory and filename to check
* @return True if the directory is valid
*/
static bool DirValid(const char* dirandfile);
/** Clean a filename, stripping the directories (and drives) from string.
* @param name Directory to tidy
* @return The cleaned filename
*/
static char* CleanFilename(char* name);
/** Check if a file exists.
* @param file The full path to a file
* @return True if the file exists and is readable.
*/
static bool FileExists(const char* file);
};
/** Initialize the disabled commands list
*/
CoreExport bool InitializeDisabledCommands(const char* data, InspIRCd* ServerInstance);
/** Initialize the oper types
*/
bool InitTypes(ServerConfig* conf, const char* tag);
/** Initialize the oper classes
*/
bool InitClasses(ServerConfig* conf, const char* tag);
/** Initialize an oper type
*/
bool DoType(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
/** Initialize an oper class
*/
bool DoClass(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
/** Finish initializing the oper types and classes
*/
bool DoneClassesAndTypes(ServerConfig* conf, const char* tag);
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef INSPIRCD_CONFIGREADER +#define INSPIRCD_CONFIGREADER + +/* handy defines */ + +/** Determines if a channel op is exempt from given mode m, + * in config of server instance s. + */ +#define CHANOPS_EXEMPT(s, m) (s->Config->ExemptChanOps[(unsigned char)m]) + +#include <sstream> +#include <string> +#include <vector> +#include <map> +#include "inspircd.h" +#include "globals.h" +#include "modules.h" +#include "socketengine.h" +#include "socket.h" + +/* Required forward definitions */ +class ServerConfig; +class InspIRCd; +class InspSocket; + +/** Types of data in the core config + */ +enum ConfigDataType +{ + DT_NOTHING = 0, /* No data */ + DT_INTEGER = 1, /* Integer */ + DT_CHARPTR = 2, /* Char pointer */ + DT_BOOLEAN = 3, /* Boolean */ + DT_ALLOW_NEWLINE = 128 /* New line characters allowed */ +}; + +/** Holds a config value, either string, integer or boolean. + * Callback functions receive one or more of these, either on + * their own as a reference, or in a reference to a deque of them. + * The callback function can then alter the values of the ValueItem + * classes to validate the settings. + */ +class ValueItem +{ + /** Actual data */ + std::string v; + public: + /** Initialize with an int */ + ValueItem(int value); + /** Initialize with a bool */ + ValueItem(bool value); + /** Initialize with a char pointer */ + ValueItem(char* value); + /** Change value to a char pointer */ + void Set(char* value); + /** Change value to a const char pointer */ + void Set(const char* val); + /** Change value to an int */ + void Set(int value); + /** Get value as an int */ + int GetInteger(); + /** Get value as a string */ + char* GetString(); + /** Get value as a bool */ + bool GetBool(); +}; + +/** The base class of the container 'ValueContainer' + * used internally by the core to hold core values. + */ +class ValueContainerBase +{ + public: + /** Constructor */ + ValueContainerBase() { } + /** Destructor */ + virtual ~ValueContainerBase() { } +}; + +/** ValueContainer is used to contain pointers to different + * core values such as the server name, maximum number of + * clients etc. + * It is specialized to hold a data type, then pointed at + * a value in the ServerConfig class. When the value has been + * read and validated, the Set method is called to write the + * value safely in a type-safe manner. + */ +template<typename T> class ValueContainer : public ValueContainerBase +{ + /** Contained item */ + T val; + public: + + /** Initialize with nothing */ + ValueContainer() + { + val = NULL; + } + + /** Initialize with a value of type T */ + ValueContainer(T Val) + { + val = Val; + } + + /** Change value to type T of size s */ + void Set(T newval, size_t s) + { + memcpy(val, newval, s); + } +}; + +/** A specialization of ValueContainer to hold a pointer to a bool + */ +typedef ValueContainer<bool*> ValueContainerBool; + +/** A specialization of ValueContainer to hold a pointer to + * an unsigned int + */ +typedef ValueContainer<unsigned int*> ValueContainerUInt; + +/** A specialization of ValueContainer to hold a pointer to + * a char array. + */ +typedef ValueContainer<char*> ValueContainerChar; + +/** A specialization of ValueContainer to hold a pointer to + * an int + */ +typedef ValueContainer<int*> ValueContainerInt; + +/** A set of ValueItems used by multi-value validator functions + */ +typedef std::deque<ValueItem> ValueList; + +/** A callback for validating a single value + */ +typedef bool (*Validator)(ServerConfig* conf, const char*, const char*, ValueItem&); +/** A callback for validating multiple value entries + */ +typedef bool (*MultiValidator)(ServerConfig* conf, const char*, char**, ValueList&, int*); +/** A callback indicating the end of a group of entries + */ +typedef bool (*MultiNotify)(ServerConfig* conf, const char*); + +/** Holds a core configuration item and its callbacks + */ +struct InitialConfig +{ + /** Tag name */ + char* tag; + /** Value name */ + char* value; + /** Default, if not defined */ + char* default_value; + /** Value containers */ + ValueContainerBase* val; + /** Data types */ + ConfigDataType datatype; + /** Validation function */ + Validator validation_function; +}; + +/** Holds a core configuration item and its callbacks + * where there may be more than one item + */ +struct MultiConfig +{ + /** Tag name */ + const char* tag; + /** One or more items within tag */ + char* items[13]; + /** One or more defaults for items within tags */ + char* items_default[13]; + /** One or more data types */ + int datatype[13]; + /** Initialization function */ + MultiNotify init_function; + /** Validation function */ + MultiValidator validation_function; + /** Completion function */ + MultiNotify finish_function; +}; + +/** A set of oper types + */ +typedef std::map<irc::string,char*> opertype_t; + +/** A Set of oper classes + */ +typedef std::map<irc::string,char*> operclass_t; + + +/** This class holds the bulk of the runtime configuration for the ircd. + * It allows for reading new config values, accessing configuration files, + * and storage of the configuration data needed to run the ircd, such as + * the servername, connect classes, /ADMIN data, MOTDs and filenames etc. + */ +class CoreExport ServerConfig : public Extensible +{ + private: + /** Creator/owner pointer + */ + InspIRCd* ServerInstance; + + /** This variable holds the names of all + * files included from the main one. This + * is used to make sure that no files are + * recursively included. + */ + std::vector<std::string> include_stack; + + /** This private method processes one line of + * configutation, appending errors to errorstream + * and setting error if an error has occured. + */ + bool ParseLine(ConfigDataHash &target, std::string &line, long linenumber, std::ostringstream &errorstream); + + /** Process an include directive + */ + bool DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream); + + /** Check that there is only one of each configuration item + */ + bool CheckOnce(char* tag, bool bail, userrec* user); + + public: + + InspIRCd* GetInstance(); + + /** This holds all the information in the config file, + * it's indexed by tag name to a vector of key/values. + */ + ConfigDataHash config_data; + + /** Max number of WhoWas entries per user. + */ + int WhoWasGroupSize; + + /** Max number of cumulative user-entries in WhoWas. + * When max reached and added to, push out oldest entry FIFO style. + */ + int WhoWasMaxGroups; + + /** Max seconds a user is kept in WhoWas before being pruned. + */ + int WhoWasMaxKeep; + + /** Holds the server name of the local server + * as defined by the administrator. + */ + char ServerName[MAXBUF]; + + /** Notice to give to users when they are Xlined + */ + char MoronBanner[MAXBUF]; + + /* Holds the network name the local server + * belongs to. This is an arbitary field defined + * by the administrator. + */ + char Network[MAXBUF]; + + /** Holds the description of the local server + * as defined by the administrator. + */ + char ServerDesc[MAXBUF]; + + /** Holds the admin's name, for output in + * the /ADMIN command. + */ + char AdminName[MAXBUF]; + + /** Holds the email address of the admin, + * for output in the /ADMIN command. + */ + char AdminEmail[MAXBUF]; + + /** Holds the admin's nickname, for output + * in the /ADMIN command + */ + char AdminNick[MAXBUF]; + + /** The admin-configured /DIE password + */ + char diepass[MAXBUF]; + + /** The admin-configured /RESTART password + */ + char restartpass[MAXBUF]; + + /** The pathname and filename of the message of the + * day file, as defined by the administrator. + */ + char motd[MAXBUF]; + + /** The pathname and filename of the rules file, + * as defined by the administrator. + */ + char rules[MAXBUF]; + + /** The quit prefix in use, or an empty string + */ + char PrefixQuit[MAXBUF]; + + /** The quit suffix in use, or an empty string + */ + char SuffixQuit[MAXBUF]; + + /** The fixed quit message in use, or an empty string + */ + char FixedQuit[MAXBUF]; + + /** The last string found within a <die> tag, or + * an empty string. + */ + char DieValue[MAXBUF]; + + /** The DNS server to use for DNS queries + */ + char DNSServer[MAXBUF]; + + /** This variable contains a space-seperated list + * of commands which are disabled by the + * administrator of the server for non-opers. + */ + char DisabledCommands[MAXBUF]; + + /** The full path to the modules directory. + * This is either set at compile time, or + * overridden in the configuration file via + * the <options> tag. + */ + char ModPath[1024]; + + /** The full pathname to the executable, as + * given in argv[0] when the program starts. + */ + char MyExecutable[1024]; + + /** The file handle of the logfile. If this + * value is NULL, the log file is not open, + * probably due to a permissions error on + * startup (this should not happen in normal + * operation!). + */ + FILE *log_file; + + /** If this value is true, the owner of the + * server specified -nofork on the command + * line, causing the daemon to stay in the + * foreground. + */ + bool nofork; + + /** If this value if true then all log + * messages will be output, regardless of + * the level given in the config file. + * This is set with the -debug commandline + * option. + */ + bool forcedebug; + + /** If this is true then log output will be + * written to the logfile. This is the default. + * If you put -nolog on the commandline then + * the logfile will not be written. + * This is meant to be used in conjunction with + * -debug for debugging without filling up the + * hard disk. + */ + bool writelog; + + /** If this value is true, halfops have been + * enabled in the configuration file. + */ + bool AllowHalfop; + + /** If this is set to true, then mode lists (e.g + * MODE #chan b) are hidden from unprivileged + * users. + */ + bool HideModeLists[256]; + + /** If this is set to true, then channel operators + * are exempt from this channel mode. Used for +Sc etc. + */ + bool ExemptChanOps[256]; + + /** The number of seconds the DNS subsystem + * will wait before timing out any request. + */ + int dns_timeout; + + /** The size of the read() buffer in the user + * handling code, used to read data into a user's + * recvQ. + */ + int NetBufferSize; + + /** The value to be used for listen() backlogs + * as default. + */ + int MaxConn; + + /** The soft limit value assigned to the irc server. + * The IRC server will not allow more than this + * number of local users. + */ + unsigned int SoftLimit; + + /** Maximum number of targets for a multi target command + * such as PRIVMSG or KICK + */ + unsigned int MaxTargets; + + /** The maximum number of /WHO results allowed + * in any single /WHO command. + */ + int MaxWhoResults; + + /** True if the DEBUG loglevel is selected. + */ + int debugging; + + /** The loglevel in use by the IRC server + */ + int LogLevel; + + /** How many seconds to wait before exiting + * the program when /DIE is correctly issued. + */ + int DieDelay; + + /** True if we're going to hide netsplits as *.net *.split for non-opers + */ + bool HideSplits; + + /** True if we're going to hide ban reasons for non-opers (e.g. G-Lines, + * K-Lines, Z-Lines) + */ + bool HideBans; + + /** Announce invites to the channel with a server notice + */ + bool AnnounceInvites; + + /** If this is enabled then operators will + * see invisible (+i) channels in /whois. + */ + bool OperSpyWhois; + + /** Set to a non-empty string to obfuscate the server name of users in WHOIS + */ + char HideWhoisServer[MAXBUF]; + + /** Set to a non empty string to obfuscate nicknames prepended to a KILL. + */ + char HideKillsServer[MAXBUF]; + + /** The MOTD file, cached in a file_cache type. + */ + file_cache MOTD; + + /** The RULES file, cached in a file_cache type. + */ + file_cache RULES; + + /** The full pathname and filename of the PID + * file as defined in the configuration. + */ + char PID[1024]; + + /** The connect classes in use by the IRC server. + */ + ClassVector Classes; + + /** A list of module names (names only, no paths) + * which are currently loaded by the server. + */ + std::vector<std::string> module_names; + + /** A list of the classes for listening client ports + */ + std::vector<ListenSocket*> ports; + + /** Boolean sets of which modules implement which functions + */ + char implement_lists[255][255]; + + /** Global implementation list + */ + char global_implementation[255]; + + /** A list of ports claimed by IO Modules + */ + std::map<int,Module*> IOHookModule; + + std::map<InspSocket*, Module*> SocketIOHookModule; + + /** The 005 tokens of this server (ISUPPORT) + * populated/repopulated upon loading or unloading + * modules. + */ + std::string data005; + + /** isupport strings + */ + std::vector<std::string> isupport; + + /** STATS characters in this list are available + * only to operators. + */ + char UserStats[MAXBUF]; + + /** The path and filename of the ircd.log file + */ + std::string logpath; + + /** Default channel modes + */ + char DefaultModes[MAXBUF]; + + /** Custom version string, which if defined can replace the system info in VERSION. + */ + char CustomVersion[MAXBUF]; + + /** List of u-lined servers + */ + std::map<irc::string, bool> ulines; + + /** Max banlist sizes for channels (the std::string is a glob) + */ + std::map<std::string, int> maxbans; + + /** Directory where the inspircd binary resides + */ + std::string MyDir; + + /** If set to true, no user DNS lookups are to be performed + */ + bool NoUserDns; + + /** If set to true, provide syntax hints for unknown commands + */ + bool SyntaxHints; + + /** If set to true, users appear to quit then rejoin when their hosts change. + * This keeps clients synchronized properly. + */ + bool CycleHosts; + + /** If set to true, prefixed channel NOTICEs and PRIVMSGs will have the prefix + * added to the outgoing text for undernet style msg prefixing. + */ + bool UndernetMsgPrefix; + + /** If set to true, the full nick!user@host will be shown in the TOPIC command + * for who set the topic last. If false, only the nick is shown. + */ + bool FullHostInTopic; + + /** All oper type definitions from the config file + */ + opertype_t opertypes; + + /** All oper class definitions from the config file + */ + operclass_t operclass; + + /** Saved argv from startup + */ + char** argv; + + /** Saved argc from startup + */ + int argc; + + /** Max channels per user + */ + unsigned int MaxChans; + + /** Oper max channels per user + */ + unsigned int OperMaxChans; + + /** Construct a new ServerConfig + */ + ServerConfig(InspIRCd* Instance); + + /** Clears the include stack in preperation for a Read() call. + */ + void ClearStack(); + + /** Update the 005 vector + */ + void Update005(); + + /** Send the 005 numerics (ISUPPORT) to a user + */ + void Send005(userrec* user); + + /** Read the entire configuration into memory + * and initialize this class. All other methods + * should be used only by the core. + */ + void Read(bool bail, userrec* user); + + /** Read a file into a file_cache object + */ + bool ReadFile(file_cache &F, const char* fname); + + /** Report a configuration error given in errormessage. + * @param bail If this is set to true, the error is sent to the console, and the program exits + * @param user If this is set to a non-null value, and bail is false, the errors are spooled to + * this user as SNOTICEs. + * If the parameter is NULL, the messages are spooled to all users via WriteOpers as SNOTICEs. + */ + void ReportConfigError(const std::string &errormessage, bool bail, userrec* user); + + /** Load 'filename' into 'target', with the new config parser everything is parsed into + * tag/key/value at load-time rather than at read-value time. + */ + bool LoadConf(ConfigDataHash &target, const char* filename, std::ostringstream &errorstream); + + /** Load 'filename' into 'target', with the new config parser everything is parsed into + * tag/key/value at load-time rather than at read-value time. + */ + bool LoadConf(ConfigDataHash &target, const std::string &filename, std::ostringstream &errorstream); + + /* Both these return true if the value existed or false otherwise */ + + /** Writes 'length' chars into 'result' as a string + */ + bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds = false); + /** Writes 'length' chars into 'result' as a string + */ + bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, char* result, int length, bool allow_linefeeds = false); + + /** Writes 'length' chars into 'result' as a string + */ + bool ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, std::string &result, bool allow_linefeeds = false); + /** Writes 'length' chars into 'result' as a string + */ + bool ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, std::string &result, bool allow_linefeeds = false); + + /** Tries to convert the value to an integer and write it to 'result' + */ + bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, int index, int &result); + /** Tries to convert the value to an integer and write it to 'result' + */ + bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, int &result); + /** Tries to convert the value to an integer and write it to 'result' + */ + bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, int &result); + /** Tries to convert the value to an integer and write it to 'result' + */ + bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, int &result); + + /** Returns true if the value exists and has a true value, false otherwise + */ + bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, int index); + /** Returns true if the value exists and has a true value, false otherwise + */ + bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index); + /** Returns true if the value exists and has a true value, false otherwise + */ + bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, int index); + /** Returns true if the value exists and has a true value, false otherwise + */ + bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index); + + /** Returns the number of occurences of tag in the config file + */ + int ConfValueEnum(ConfigDataHash &target, const char* tag); + /** Returns the number of occurences of tag in the config file + */ + int ConfValueEnum(ConfigDataHash &target, const std::string &tag); + + /** Returns the numbers of vars inside the index'th 'tag in the config file + */ + int ConfVarEnum(ConfigDataHash &target, const char* tag, int index); + /** Returns the numbers of vars inside the index'th 'tag in the config file + */ + int ConfVarEnum(ConfigDataHash &target, const std::string &tag, int index); + + /** Get a pointer to the module which has hooked the given port. + * @parameter port Port number + * @return Returns a pointer to the hooking module, or NULL + */ + Module* GetIOHook(int port); + + /** Hook a module to a client port, so that it can receive notifications + * of low-level port activity. + * @param port The port number + * @param Module the module to hook to the port + * @return True if the hook was successful. + */ + bool AddIOHook(int port, Module* iomod); + + /** Delete a module hook from a client port. + * @param port The port to detatch from + * @return True if successful + */ + bool DelIOHook(int port); + + /** Get a pointer to the module which has hooked the given InspSocket class. + * @parameter port Port number + * @return Returns a pointer to the hooking module, or NULL + */ + Module* GetIOHook(InspSocket* is); + + /** Hook a module to an InspSocket class, so that it can receive notifications + * of low-level socket activity. + * @param iomod The module to hook to the socket + * @param is The InspSocket to attach to + * @return True if the hook was successful. + */ + bool AddIOHook(Module* iomod, InspSocket* is); + + /** Delete a module hook from an InspSocket. + * @param is The InspSocket to detatch from. + * @return True if the unhook was successful + */ + bool DelIOHook(InspSocket* is); + + /** Returns the fully qualified path to the inspircd directory + * @return The full program directory + */ + std::string GetFullProgDir(); + + /** Returns true if a directory is valid (within the modules directory). + * @param dirandfile The directory and filename to check + * @return True if the directory is valid + */ + static bool DirValid(const char* dirandfile); + + /** Clean a filename, stripping the directories (and drives) from string. + * @param name Directory to tidy + * @return The cleaned filename + */ + static char* CleanFilename(char* name); + + /** Check if a file exists. + * @param file The full path to a file + * @return True if the file exists and is readable. + */ + static bool FileExists(const char* file); + +}; + +/** Initialize the disabled commands list + */ +CoreExport bool InitializeDisabledCommands(const char* data, InspIRCd* ServerInstance); + +/** Initialize the oper types + */ +bool InitTypes(ServerConfig* conf, const char* tag); + +/** Initialize the oper classes + */ +bool InitClasses(ServerConfig* conf, const char* tag); + +/** Initialize an oper type + */ +bool DoType(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types); + +/** Initialize an oper class + */ +bool DoClass(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types); + +/** Finish initializing the oper types and classes + */ +bool DoneClassesAndTypes(ServerConfig* conf, const char* tag); + +#endif + diff --git a/include/connection.h b/include/connection.h index 1641b976d..65d342447 100644 --- a/include/connection.h +++ b/include/connection.h @@ -1 +1,79 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __CONNECTION_H__
#define __CONNECTION_H__
#include <time.h>
#include "inspircd_config.h"
#include "base.h"
#include "socketengine.h"
/** connection is the base class of userrec, and holds basic user properties.
* This can be extended for holding other user-like objects in the future.
*/
class CoreExport connection : public EventHandler
{
public:
/** Hostname of connection.
* This should be valid as per RFC1035.
*/
char host[65];
/** Stats counter for bytes inbound
*/
int bytes_in;
/** Stats counter for bytes outbound
*/
int bytes_out;
/** Stats counter for commands inbound
*/
int cmds_in;
/** Stats counter for commands outbound
*/
int cmds_out;
/** True if user has authenticated, false if otherwise
*/
bool haspassed;
/** Used by userrec to indicate the registration status of the connection
* It is a bitfield of the REG_NICK, REG_USER and REG_ALL bits to indicate
* the connection state.
*/
char registered;
/** Time the connection was last pinged
*/
time_t lastping;
/** Time the connection was created, set in the constructor. This
* may be different from the time the user's classbase object was
* created.
*/
time_t signon;
/** Time that the connection last sent a message, used to calculate idle time
*/
time_t idle_lastmsg;
/** Used by PING checking code
*/
time_t nping;
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __CONNECTION_H__ +#define __CONNECTION_H__ + +#include <time.h> +#include "inspircd_config.h" +#include "base.h" +#include "socketengine.h" + +/** connection is the base class of userrec, and holds basic user properties. + * This can be extended for holding other user-like objects in the future. + */ +class CoreExport connection : public EventHandler +{ + public: + /** Hostname of connection. + * This should be valid as per RFC1035. + */ + char host[65]; + + /** Stats counter for bytes inbound + */ + int bytes_in; + + /** Stats counter for bytes outbound + */ + int bytes_out; + + /** Stats counter for commands inbound + */ + int cmds_in; + + /** Stats counter for commands outbound + */ + int cmds_out; + + /** True if user has authenticated, false if otherwise + */ + bool haspassed; + + /** Used by userrec to indicate the registration status of the connection + * It is a bitfield of the REG_NICK, REG_USER and REG_ALL bits to indicate + * the connection state. + */ + char registered; + + /** Time the connection was last pinged + */ + time_t lastping; + + /** Time the connection was created, set in the constructor. This + * may be different from the time the user's classbase object was + * created. + */ + time_t signon; + + /** Time that the connection last sent a message, used to calculate idle time + */ + time_t idle_lastmsg; + + /** Used by PING checking code + */ + time_t nping; +}; + + +#endif diff --git a/include/ctables.h b/include/ctables.h index d8d76100e..e8a3337fd 100644 --- a/include/ctables.h +++ b/include/ctables.h @@ -1 +1,172 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __CTABLES_H__
#define __CTABLES_H__
#include "inspircd_config.h"
#include "hash_map.h"
#include "base.h"
/* Forward declarations - required */
class userrec;
class InspIRCd;
/** Used to indicate command success codes
*/
enum CmdResult
{
CMD_FAILURE = 0, /* Command exists, but failed */
CMD_SUCCESS = 1, /* Command exists, and succeeded */
CMD_INVALID = 2, /* Command doesnt exist at all! */
CMD_USER_DELETED = 3 /* User was deleted - DEPRECIATED */
};
/** For commands which should not be replicated to other
* servers, we usually return CMD_FAILURE. this isnt readable,
* so we define this alias for CMD_FAILURE called
* CMD_LOCALONLY, which of course does the same thing but is
* much more readable.
*/
#define CMD_LOCALONLY CMD_FAILURE
/** A structure that defines a command. Every command available
* in InspIRCd must be defined as derived from command_t.
*/
class CoreExport command_t : public Extensible
{
protected:
/** Owner/Creator object
*/
InspIRCd* ServerInstance;
public:
/** Command name
*/
std::string command;
/** User flags needed to execute the command or 0
*/
char flags_needed;
/** Minimum number of parameters command takes
*/
int min_params;
/** used by /stats m
*/
long use_count;
/** used by /stats m
*/
float total_bytes;
/** used for resource tracking between modules
*/
std::string source;
/** True if the command is disabled to non-opers
*/
bool disabled;
/** True if the command can be issued before registering
*/
bool works_before_reg;
/** Syntax string for the command, displayed if non-empty string.
* This takes place of the text in the 'not enough parameters' numeric.
*/
std::string syntax;
/** Create a new command.
* @param Instance Pointer to creator class
* @param cmd Command name. This must be UPPER CASE.
* @param flags User modes required to execute the command.
* For oper only commands, set this to 'o', otherwise use 0.
* @param minpara Minimum parameters required for the command.
* @param before_reg If this is set to true, the command will
* be allowed before the user is 'registered' (has sent USER,
* NICK, optionally PASS, and been resolved).
*/
command_t(InspIRCd* Instance, const std::string &cmd, char flags, int minpara, int before_reg = false) : ServerInstance(Instance), command(cmd), flags_needed(flags), min_params(minpara), disabled(false), works_before_reg(before_reg)
{
use_count = 0;
total_bytes = 0;
source = "<core>";
syntax = "";
}
/** Handle the command from a user.
* @param parameters The parameters for the command.
* @param pcnt The number of parameters available in 'parameters'
* @param user The user who issued the command.
* @return Return CMD_SUCCESS on success, or CMD_FAILURE on failure.
* If the command succeeds but should remain local to this server,
* return CMD_LOCALONLY.
*/
virtual CmdResult Handle(const char** parameters, int pcnt, userrec* user) = 0;
/** Handle an internal request from another command, the core, or a module
* @param Command ID
* @param Zero or more parameters, whos form is specified by the command ID.
* @return Return CMD_SUCCESS on success, or CMD_FAILURE on failure.
* If the command succeeds but should remain local to this server,
* return CMD_LOCALONLY.
*/
virtual CmdResult HandleInternal(const unsigned int id, const std::deque<classbase*> ¶ms)
{
return CMD_INVALID;
}
/** Handle the command from a server.
* Not currently used in this version of InspIRCd.
* @param parameters The parameters given
* @param pcnt The number of parameters available
* @param servername The server name which issued the command
* @return Return CMD_SUCCESS on success, or CMD_FAILURE on failure.
* If the command succeeds but should remain local to this server,
* return CMD_LOCALONLY.
*/
virtual CmdResult HandleServer(const char** parameters, int pcnt, const std::string &servername)
{
return CMD_INVALID;
}
/** Disable or enable this command.
* @param setting True to disable the command.
*/
void Disable(bool setting)
{
disabled = setting;
}
/** Obtain this command's disable state.
* @return true if the command is currently disabled
* (disabled commands can be used only by operators)
*/
bool IsDisabled()
{
return disabled;
}
/** @return true if the command works before registration.
*/
bool WorksBeforeReg()
{
return works_before_reg;
}
/** Standard constructor gubbins
*/
virtual ~command_t() {}
};
/** A hash of commands used by the core
*/
typedef nspace::hash_map<std::string,command_t*> command_table;
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __CTABLES_H__ +#define __CTABLES_H__ + + +#include "inspircd_config.h" +#include "hash_map.h" +#include "base.h" + +/* Forward declarations - required */ +class userrec; +class InspIRCd; + +/** Used to indicate command success codes + */ +enum CmdResult +{ + CMD_FAILURE = 0, /* Command exists, but failed */ + CMD_SUCCESS = 1, /* Command exists, and succeeded */ + CMD_INVALID = 2, /* Command doesnt exist at all! */ + CMD_USER_DELETED = 3 /* User was deleted - DEPRECIATED */ +}; + +/** For commands which should not be replicated to other + * servers, we usually return CMD_FAILURE. this isnt readable, + * so we define this alias for CMD_FAILURE called + * CMD_LOCALONLY, which of course does the same thing but is + * much more readable. + */ +#define CMD_LOCALONLY CMD_FAILURE + + +/** A structure that defines a command. Every command available + * in InspIRCd must be defined as derived from command_t. + */ +class CoreExport command_t : public Extensible +{ + protected: + /** Owner/Creator object + */ + InspIRCd* ServerInstance; + public: + /** Command name + */ + std::string command; + /** User flags needed to execute the command or 0 + */ + char flags_needed; + /** Minimum number of parameters command takes + */ + int min_params; + /** used by /stats m + */ + long use_count; + /** used by /stats m + */ + float total_bytes; + /** used for resource tracking between modules + */ + std::string source; + /** True if the command is disabled to non-opers + */ + bool disabled; + /** True if the command can be issued before registering + */ + bool works_before_reg; + /** Syntax string for the command, displayed if non-empty string. + * This takes place of the text in the 'not enough parameters' numeric. + */ + std::string syntax; + + /** Create a new command. + * @param Instance Pointer to creator class + * @param cmd Command name. This must be UPPER CASE. + * @param flags User modes required to execute the command. + * For oper only commands, set this to 'o', otherwise use 0. + * @param minpara Minimum parameters required for the command. + * @param before_reg If this is set to true, the command will + * be allowed before the user is 'registered' (has sent USER, + * NICK, optionally PASS, and been resolved). + */ + command_t(InspIRCd* Instance, const std::string &cmd, char flags, int minpara, int before_reg = false) : ServerInstance(Instance), command(cmd), flags_needed(flags), min_params(minpara), disabled(false), works_before_reg(before_reg) + { + use_count = 0; + total_bytes = 0; + source = "<core>"; + syntax = ""; + } + + /** Handle the command from a user. + * @param parameters The parameters for the command. + * @param pcnt The number of parameters available in 'parameters' + * @param user The user who issued the command. + * @return Return CMD_SUCCESS on success, or CMD_FAILURE on failure. + * If the command succeeds but should remain local to this server, + * return CMD_LOCALONLY. + */ + virtual CmdResult Handle(const char** parameters, int pcnt, userrec* user) = 0; + + /** Handle an internal request from another command, the core, or a module + * @param Command ID + * @param Zero or more parameters, whos form is specified by the command ID. + * @return Return CMD_SUCCESS on success, or CMD_FAILURE on failure. + * If the command succeeds but should remain local to this server, + * return CMD_LOCALONLY. + */ + virtual CmdResult HandleInternal(const unsigned int id, const std::deque<classbase*> ¶ms) + { + return CMD_INVALID; + } + + /** Handle the command from a server. + * Not currently used in this version of InspIRCd. + * @param parameters The parameters given + * @param pcnt The number of parameters available + * @param servername The server name which issued the command + * @return Return CMD_SUCCESS on success, or CMD_FAILURE on failure. + * If the command succeeds but should remain local to this server, + * return CMD_LOCALONLY. + */ + virtual CmdResult HandleServer(const char** parameters, int pcnt, const std::string &servername) + { + return CMD_INVALID; + } + + /** Disable or enable this command. + * @param setting True to disable the command. + */ + void Disable(bool setting) + { + disabled = setting; + } + + /** Obtain this command's disable state. + * @return true if the command is currently disabled + * (disabled commands can be used only by operators) + */ + bool IsDisabled() + { + return disabled; + } + + /** @return true if the command works before registration. + */ + bool WorksBeforeReg() + { + return works_before_reg; + } + + /** Standard constructor gubbins + */ + virtual ~command_t() {} +}; + +/** A hash of commands used by the core + */ +typedef nspace::hash_map<std::string,command_t*> command_table; + +#endif + diff --git a/include/cull_list.h b/include/cull_list.h index b2742e390..129f0d43d 100644 --- a/include/cull_list.h +++ b/include/cull_list.h @@ -1 +1,162 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __CULLLIST_H__
#define __CULLLIST_H__
// include the common header files
#include <string>
#include <deque>
#include <vector>
#include "users.h"
#include "channels.h"
class InspIRCd;
/** The CullItem class holds a user and their quitmessage,
* and is used internally by the CullList class to compile
* a list of users which are to be culled when a long
* operation (such as a netsplit) has completed.
*/
class CoreExport CullItem : public classbase
{
private:
/** Holds a pointer to the user,
* must be valid and can be a local or remote user.
*/
userrec* user;
/** Holds the quit reason to use for this user.
*/
std::string reason;
/** Holds the quit reason opers see, if different from users
*/
std::string oper_reason;
/** Silent items dont generate an snotice.
*/
bool silent;
public:
/** Constrcutor.
* Initializes the CullItem with a user pointer
* and their quit reason
* @param u The user to add
* @param r The quit reason of the added user
* @param ro The quit reason to show to opers only
*/
CullItem(userrec* u, std::string &r, const char* ro = "");
/** Constrcutor.
* Initializes the CullItem with a user pointer
* and their quit reason
* @param u The user to add
* @param r The quit reason of the added user
* @param ro The quit reason to show to opers only
*/
CullItem(userrec* u, const char* r, const char* ro = "");
/** Make the quit silent a module is dealing with
* displaying this users quit, so we shouldn't
* send anything out.
*/
void MakeSilent();
/** Returns true if the quit for this user has been set
* to silent.
*/
bool IsSilent();
/** Destructor
*/
~CullItem();
/** Returns a pointer to the user
*/
userrec* GetUser();
/** Returns the user's quit reason
*/
std::string& GetReason();
/** Returns oper reason
*/
std::string& GetOperReason();
};
/** The CullList class can be used by modules, and is used
* by the core, to compile large lists of users in preperation
* to quitting them all at once. This is faster than quitting
* them within the loop, as the loops become tighter with
* little or no comparisons within them. The CullList class
* operates by allowing the programmer to push users onto
* the list, each with a seperate quit reason, and then, once
* the list is complete, call a method to flush the list,
* quitting all the users upon it. A CullList may hold local
* or remote users, but it may only hold each user once. If
* you attempt to add the same user twice, then the second
* attempt will be ignored.
*/
class CoreExport CullList : public classbase
{
private:
/** Creator of this CullList
*/
InspIRCd* ServerInstance;
/** Holds a list of users already added for quick lookup
*/
std::map<userrec*, userrec*> exempt;
/** Holds a list of users being quit.
* See the information for CullItem for
* more information.
*/
std::vector<CullItem> list;
public:
/** Constructor.
* Clears the CullList::list and CullList::exempt
* items.
* @param Instance Creator of this CullList object
*/
CullList(InspIRCd* Instance);
/** Adds a user to the cull list for later
* removal via QUIT.
* @param user The user to add
* @param reason The quit reason of the user being added
* @param o_reason The quit reason to show only to opers
*/
void AddItem(userrec* user, std::string &reason, const char* o_reason = "");
/** Adds a user to the cull list for later
* removal via QUIT.
* @param user The user to add
* @param reason The quit reason of the user being added
* @param o_reason The quit reason to show only to opers
*/
void AddItem(userrec* user, const char* reason, const char* o_reason = "");
/* Turn an item into a silent item (don't send out QUIT for this user)
*/
void MakeSilent(userrec* user);
/** Applies the cull list, quitting all the users
* on the list with their quit reasons all at once.
* This is a very fast operation compared to
* iterating the user list and comparing each one,
* especially if there are multiple comparisons
* to be done, or recursion.
* @returns The number of users removed from IRC.
*/
int Apply();
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __CULLLIST_H__ +#define __CULLLIST_H__ + +// include the common header files + +#include <string> +#include <deque> +#include <vector> +#include "users.h" +#include "channels.h" + +class InspIRCd; + +/** The CullItem class holds a user and their quitmessage, + * and is used internally by the CullList class to compile + * a list of users which are to be culled when a long + * operation (such as a netsplit) has completed. + */ +class CoreExport CullItem : public classbase +{ + private: + /** Holds a pointer to the user, + * must be valid and can be a local or remote user. + */ + userrec* user; + /** Holds the quit reason to use for this user. + */ + std::string reason; + /** Holds the quit reason opers see, if different from users + */ + std::string oper_reason; + /** Silent items dont generate an snotice. + */ + bool silent; + public: + /** Constrcutor. + * Initializes the CullItem with a user pointer + * and their quit reason + * @param u The user to add + * @param r The quit reason of the added user + * @param ro The quit reason to show to opers only + */ + CullItem(userrec* u, std::string &r, const char* ro = ""); + /** Constrcutor. + * Initializes the CullItem with a user pointer + * and their quit reason + * @param u The user to add + * @param r The quit reason of the added user + * @param ro The quit reason to show to opers only + */ + CullItem(userrec* u, const char* r, const char* ro = ""); + + /** Make the quit silent a module is dealing with + * displaying this users quit, so we shouldn't + * send anything out. + */ + void MakeSilent(); + + /** Returns true if the quit for this user has been set + * to silent. + */ + bool IsSilent(); + + /** Destructor + */ + ~CullItem(); + + /** Returns a pointer to the user + */ + userrec* GetUser(); + /** Returns the user's quit reason + */ + std::string& GetReason(); + /** Returns oper reason + */ + std::string& GetOperReason(); +}; + +/** The CullList class can be used by modules, and is used + * by the core, to compile large lists of users in preperation + * to quitting them all at once. This is faster than quitting + * them within the loop, as the loops become tighter with + * little or no comparisons within them. The CullList class + * operates by allowing the programmer to push users onto + * the list, each with a seperate quit reason, and then, once + * the list is complete, call a method to flush the list, + * quitting all the users upon it. A CullList may hold local + * or remote users, but it may only hold each user once. If + * you attempt to add the same user twice, then the second + * attempt will be ignored. + */ +class CoreExport CullList : public classbase +{ + private: + /** Creator of this CullList + */ + InspIRCd* ServerInstance; + + /** Holds a list of users already added for quick lookup + */ + std::map<userrec*, userrec*> exempt; + + /** Holds a list of users being quit. + * See the information for CullItem for + * more information. + */ + std::vector<CullItem> list; + + public: + /** Constructor. + * Clears the CullList::list and CullList::exempt + * items. + * @param Instance Creator of this CullList object + */ + CullList(InspIRCd* Instance); + + /** Adds a user to the cull list for later + * removal via QUIT. + * @param user The user to add + * @param reason The quit reason of the user being added + * @param o_reason The quit reason to show only to opers + */ + void AddItem(userrec* user, std::string &reason, const char* o_reason = ""); + + /** Adds a user to the cull list for later + * removal via QUIT. + * @param user The user to add + * @param reason The quit reason of the user being added + * @param o_reason The quit reason to show only to opers + */ + void AddItem(userrec* user, const char* reason, const char* o_reason = ""); + + /* Turn an item into a silent item (don't send out QUIT for this user) + */ + void MakeSilent(userrec* user); + + /** Applies the cull list, quitting all the users + * on the list with their quit reasons all at once. + * This is a very fast operation compared to + * iterating the user list and comparing each one, + * especially if there are multiple comparisons + * to be done, or recursion. + * @returns The number of users removed from IRC. + */ + int Apply(); +}; + +#endif + diff --git a/include/dns.h b/include/dns.h index 279c2bc61..b00c57201 100644 --- a/include/dns.h +++ b/include/dns.h @@ -1 +1,520 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
/*
dns.h - dns library very very loosely based on
firedns, Copyright (C) 2002 Ian Gulliver
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _DNS_H
#define _DNS_H
#include <string>
#include "inspircd_config.h"
#include "base.h"
#include "socketengine.h"
#include "socket.h"
#include "hash_map.h"
#include "hashcomp.h"
using namespace std;
using irc::sockets::insp_aton;
using irc::sockets::insp_ntoa;
using irc::sockets::insp_sockaddr;
using irc::sockets::insp_inaddr;
class InspIRCd;
class Module;
/**
* Result status, used internally
*/
class CoreExport DNSResult : public classbase
{
public:
/** Result ID
*/
int id;
/** Result body, a hostname or IP address
*/
std::string result;
/** Time-to-live value of the result
*/
unsigned long ttl;
/** The original request, a hostname or IP address
*/
std::string original;
/** Build a DNS result.
* @param i The request ID
* @param res The request result, a hostname or IP
* @param timetolive The request time-to-live
* @param orig The original request, a hostname or IP
*/
DNSResult(int i, const std::string &res, unsigned long timetolive, const std::string &orig) : id(i), result(res), ttl(timetolive), original(orig) { }
};
/**
* Information on a completed lookup, used internally
*/
typedef std::pair<unsigned char*, std::string> DNSInfo;
/** Cached item stored in the query cache.
*/
class CoreExport CachedQuery
{
public:
/** The cached result data, an IP or hostname
*/
std::string data;
/** The time when the item is due to expire
*/
time_t expires;
/** Build a cached query
* @param res The result data, an IP or hostname
* @param ttl The time-to-live value of the query result
*/
CachedQuery(const std::string &res, unsigned int ttl) : data(res)
{
expires = time(NULL) + ttl;
}
/** Returns the number of seconds remaining before this
* cache item has expired and should be removed.
*/
int CalcTTLRemaining()
{
int n = (int)expires - (int)time(NULL);
return (n < 0 ? 0 : n);
}
};
/** DNS cache information. Holds IPs mapped to hostnames, and hostnames mapped to IPs.
*/
#ifndef WIN32
typedef nspace::hash_map<irc::string, CachedQuery, nspace::hash<irc::string> > dnscache;
#else
typedef nspace::hash_map<irc::string, CachedQuery, nspace::hash_compare<irc::string> > dnscache;
#endif
/**
* Error types that class Resolver can emit to its error method.
*/
enum ResolverError
{
RESOLVER_NOERROR = 0,
RESOLVER_NSDOWN = 1,
RESOLVER_NXDOMAIN = 2,
RESOLVER_NOTREADY = 3,
RESOLVER_BADIP = 4,
RESOLVER_TIMEOUT = 5,
RESLOVER_FORCEUNLOAD = 6
};
/**
* A DNS request
*/
class DNSRequest;
/**
* A DNS packet header
*/
class DNSHeader;
/**
* A DNS Resource Record (rr)
*/
struct ResourceRecord;
/**
* Query and resource record types
*/
enum QueryType
{
DNS_QUERY_NONE = 0, /* Uninitialized Query */
DNS_QUERY_A = 1, /* 'A' record: an ipv4 address */
DNS_QUERY_CNAME = 5, /* 'CNAME' record: An alias */
DNS_QUERY_PTR = 12, /* 'PTR' record: a hostname */
DNS_QUERY_AAAA = 28, /* 'AAAA' record: an ipv6 address */
DNS_QUERY_PTR4 = 0xFFFD, /* Force 'PTR' to use IPV4 scemantics */
DNS_QUERY_PTR6 = 0xFFFE /* Force 'PTR' to use IPV6 scemantics */
};
#ifdef IPV6
const QueryType DNS_QUERY_FORWARD = DNS_QUERY_AAAA;
#else
const QueryType DNS_QUERY_FORWARD = DNS_QUERY_A;
#endif
const QueryType DNS_QUERY_REVERSE = DNS_QUERY_PTR;
/**
* Used internally to force PTR lookups to use a certain protocol scemantics,
* e.g. x.x.x.x.in-addr.arpa for v4, and *.ip6.arpa for v6.
*/
enum ForceProtocol
{
PROTOCOL_IPV4 = 0, /* Forced to use ipv4 */
PROTOCOL_IPV6 = 1 /* Forced to use ipv6 */
};
/**
* The Resolver class is a high-level abstraction for resolving DNS entries.
* It can do forward and reverse IPv4 lookups, and where IPv6 is supported, will
* also be able to do those, transparent of protocols. Module developers must
* extend this class via inheritence, and then insert a pointer to their derived
* class into the core using Server::AddResolver(). Once you have done this,
* the class will be able to receive callbacks. There are two callbacks which
* can occur by calling virtual methods, one is a success situation, and the other
* an error situation.
*/
class CoreExport Resolver : public Extensible
{
protected:
/**
* Pointer to creator
*/
InspIRCd* ServerInstance;
/**
* Pointer to creator module (if any, or NULL)
*/
Module* Creator;
/**
* The input data, either a host or an IP address
*/
std::string input;
/**
* True if a forward lookup is being performed, false if otherwise
*/
QueryType querytype;
/**
* The DNS erver being used for lookups. If this is an empty string,
* the value of ServerConfig::DNSServer is used instead.
*/
std::string server;
/**
* The ID allocated to your lookup. This is a pseudo-random number
* between 0 and 65535, a value of -1 indicating a failure.
* The core uses this to route results to the correct objects.
*/
int myid;
/**
* Cached result, if there is one
*/
CachedQuery *CQ;
/**
* Time left before cache expiry
*/
int time_left;
public:
/**
* Initiate DNS lookup. Your class should not attempt to delete or free these
* objects, as the core will do this for you. They must always be created upon
* the heap using new, as you cannot be sure at what time they will be deleted.
* Allocating them on the stack or attempting to delete them yourself could cause
* the object to go 'out of scope' and cause a segfault in the core if the result
* arrives at a later time.
* @param source The IP or hostname to resolve
* @param qt The query type to perform. If you just want to perform a forward
* or reverse lookup, and you don't care wether you get ipv4 or ipv6, then use
* the constants DNS_QUERY_FORWARD and DNS_QUERY_REVERSE, which automatically
* select from 'A' record or 'AAAA' record lookups. However, if you want to resolve
* a specific record type, resolution of 'A', 'AAAA', 'PTR' and 'CNAME' records
* is supported. Use one of the QueryType enum values to initiate this type of
* lookup. Resolution of 'AAAA' ipv6 records is always supported, regardless of
* wether InspIRCd is built with ipv6 support.
* If you attempt to resolve a 'PTR' record using DNS_QUERY_PTR, and InspIRCd is
* built with ipv6 support, the 'PTR' record will be formatted to ipv6 specs,
* e.g. x.x.x.x.x....ip6.arpa. otherwise it will be formatted to ipv4 specs,
* e.g. x.x.x.x.in-addr.arpa. This translation is automatic.
* To get around this automatic behaviour, you must use one of the values
* DNS_QUERY_PTR4 or DNS_QUERY_PTR6 to force ipv4 or ipv6 behaviour on the lookup,
* irrespective of what protocol InspIRCd has been built for.
* @param cached The constructor will set this boolean to true or false depending
* on whether the DNS lookup you are attempting is cached (and not expired) or not.
* If the value is cached, upon return this will be set to true, otherwise it will
* be set to false. You should pass this value to InspIRCd::AddResolver(), which
* will then influence the behaviour of the method and determine whether a cached
* or non-cached result is obtained. The value in this variable is always correct
* for the given request when the constructor exits.
* @param creator See the note below.
* @throw ModuleException This class may throw an instance of ModuleException, in the
* event a lookup could not be allocated, or a similar hard error occurs such as
* the network being down. This will also be thrown if an invalid IP address is
* passed when resolving a 'PTR' record.
*
* NOTE: If you are instantiating your DNS lookup from a module, you should set the
* value of creator to point at your Module class. This way if your module is unloaded
* whilst lookups are in progress, they can be safely removed and your module will not
* crash the server.
*/
Resolver(InspIRCd* Instance, const std::string &source, QueryType qt, bool &cached, Module* creator = NULL);
/**
* The default destructor does nothing.
*/
virtual ~Resolver();
/**
* When your lookup completes, this method will be called.
* @param result The resulting DNS lookup, either an IP address or a hostname.
* @param ttl The time-to-live value of the result, in the instance of a cached
* result, this is the number of seconds remaining before refresh/expiry.
* @param cached True if the result is a cached result, false if it was requested
* from the DNS server.
*/
virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached) = 0;
/**
* If an error occurs (such as NXDOMAIN, no domain name found) then this method
* will be called.
* @param e A ResolverError enum containing the error type which has occured.
* @param errormessage The error text of the error that occured.
*/
virtual void OnError(ResolverError e, const std::string &errormessage);
/**
* Returns the id value of this class. This is primarily used by the core
* to determine where in various tables to place a pointer to your class, but it
* is safe to call and use this method.
* As specified in RFC1035, each dns request has a 16 bit ID value, ranging
* from 0 to 65535. If there is an issue and the core cannot send your request,
* this method will return -1.
*/
int GetId();
/**
* Returns the creator module, or NULL
*/
Module* GetCreator();
/**
* If the result is a cached result, this triggers the objects
* OnLookupComplete. This is done because it is not safe to call
* the abstract virtual method from the constructor.
*/
void TriggerCachedResult();
};
/** DNS is a singleton class used by the core to dispatch dns
* requests to the dns server, and route incoming dns replies
* back to Resolver objects, based upon the request ID. You
* should never use this class yourself.
*/
class CoreExport DNS : public EventHandler
{
private:
/**
* Creator/Owner object
*/
InspIRCd* ServerInstance;
/**
* The maximum value of a dns request id,
* 16 bits wide, 0xFFFF.
*/
static const int MAX_REQUEST_ID = 0xFFFF;
/**
* A counter used to form part of the pseudo-random id
*/
int currid;
/**
* We have to turn off a few checks on received packets
* when people are using 4in6 (e.g. ::ffff:xxxx). This is
* a temporary kludge, Please let me know if you know how
* to fix it.
*/
bool ip6munge;
/**
* Currently cached items
*/
dnscache* cache;
/** A timer which ticks every hour to remove expired
* items from the DNS cache.
*/
class CacheTimer* PruneTimer;
/**
* Build a dns packet payload
*/
int MakePayload(const char* name, const QueryType rr, const unsigned short rr_class, unsigned char* payload);
public:
/**
* Server address being used currently
*/
int socketfamily;
#ifdef IPV6
in6_addr myserver6;
#endif
in_addr myserver4;
/**
* Currently active Resolver classes
*/
Resolver* Classes[MAX_REQUEST_ID];
/**
* Requests that are currently 'in flight'
*/
DNSRequest* requests[MAX_REQUEST_ID];
/**
* The port number DNS requests are made on,
* and replies have as a source-port number.
*/
static const int QUERY_PORT = 53;
/**
* Fill an rr (resource record) with data from input
*/
static void FillResourceRecord(ResourceRecord* rr, const unsigned char* input);
/**
* Fill a header with data from input limited by a length
*/
static void FillHeader(DNSHeader *header, const unsigned char *input, const int length);
/**
* Empty out a header into a data stream ready for transmission "on the wire"
*/
static void EmptyHeader(unsigned char *output, const DNSHeader *header, const int length);
/**
* Start the lookup of an ipv4 from a hostname
*/
int GetIP(const char* name);
/**
* Start the lookup of a hostname from an ip,
* always using the protocol inspircd is built for,
* e.g. use ipv6 reverse lookup when built for ipv6,
* or ipv4 lookup when built for ipv4.
*/
int GetName(const insp_inaddr* ip);
/**
* Start lookup of a hostname from an ip, but
* force a specific protocol to be used for the lookup
* for example to perform an ipv6 reverse lookup.
*/
int GetNameForce(const char *ip, ForceProtocol fp);
/**
* Start lookup of an ipv6 from a hostname
*/
int GetIP6(const char *name);
/**
* Start lookup of a CNAME from another hostname
*/
int GetCName(const char* alias);
/**
* Fetch the result string (an ip or host)
* and/or an error message to go with it.
*/
DNSResult GetResult();
/**
* Handle a SocketEngine read event
* Inherited from EventHandler
*/
void HandleEvent(EventType et, int errornum = 0);
/**
* Add a Resolver* to the list of active classes
*/
bool AddResolverClass(Resolver* r);
/**
* Add a query to the list to be sent
*/
DNSRequest* AddQuery(DNSHeader *header, int &id, const char* original);
/**
* The constructor initialises the dns socket,
* and clears the request lists.
*/
DNS(InspIRCd* Instance);
/**
* Re-initialize the DNS subsystem.
*/
void Rehash();
/**
* Destructor
*/
~DNS();
/** Portable random number generator, generates
* its random number from the ircd stats counters,
* effective user id, time of day and the rollover
* counter (currid)
*/
unsigned long PRNG();
/**
* Turn an in6_addr into a .ip6.arpa domain
*/
static void MakeIP6Int(char* query, const in6_addr *ip);
/**
* Clean out all dns resolvers owned by a particular
* module, to make unloading a module safe if there
* are dns requests currently in progress.
*/
void CleanResolvers(Module* module);
/** Return the cached value of an IP or hostname
* @param source An IP or hostname to find in the cache.
* @return A pointer to a CachedQuery if the item exists,
* otherwise NULL.
*/
CachedQuery* GetCache(const std::string &source);
/** Delete a cached item from the DNS cache.
* @param source An IP or hostname to remove
*/
void DelCache(const std::string &source);
/** Clear all items from the DNS cache immediately.
*/
int ClearCache();
/** Prune the DNS cache, e.g. remove all expired
* items and rehash the cache buckets, but leave
* items in the hash which are still valid.
*/
int PruneCache();
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +/* +dns.h - dns library very very loosely based on +firedns, Copyright (C) 2002 Ian Gulliver + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _DNS_H +#define _DNS_H + +#include <string> +#include "inspircd_config.h" +#include "base.h" +#include "socketengine.h" +#include "socket.h" +#include "hash_map.h" +#include "hashcomp.h" + +using namespace std; +using irc::sockets::insp_aton; +using irc::sockets::insp_ntoa; +using irc::sockets::insp_sockaddr; +using irc::sockets::insp_inaddr; + +class InspIRCd; +class Module; + +/** + * Result status, used internally + */ +class CoreExport DNSResult : public classbase +{ + public: + /** Result ID + */ + int id; + /** Result body, a hostname or IP address + */ + std::string result; + /** Time-to-live value of the result + */ + unsigned long ttl; + /** The original request, a hostname or IP address + */ + std::string original; + + /** Build a DNS result. + * @param i The request ID + * @param res The request result, a hostname or IP + * @param timetolive The request time-to-live + * @param orig The original request, a hostname or IP + */ + DNSResult(int i, const std::string &res, unsigned long timetolive, const std::string &orig) : id(i), result(res), ttl(timetolive), original(orig) { } +}; + +/** + * Information on a completed lookup, used internally + */ +typedef std::pair<unsigned char*, std::string> DNSInfo; + +/** Cached item stored in the query cache. + */ +class CoreExport CachedQuery +{ + public: + /** The cached result data, an IP or hostname + */ + std::string data; + /** The time when the item is due to expire + */ + time_t expires; + + /** Build a cached query + * @param res The result data, an IP or hostname + * @param ttl The time-to-live value of the query result + */ + CachedQuery(const std::string &res, unsigned int ttl) : data(res) + { + expires = time(NULL) + ttl; + } + + /** Returns the number of seconds remaining before this + * cache item has expired and should be removed. + */ + int CalcTTLRemaining() + { + int n = (int)expires - (int)time(NULL); + return (n < 0 ? 0 : n); + } +}; + +/** DNS cache information. Holds IPs mapped to hostnames, and hostnames mapped to IPs. + */ +#ifndef WIN32 +typedef nspace::hash_map<irc::string, CachedQuery, nspace::hash<irc::string> > dnscache; +#else +typedef nspace::hash_map<irc::string, CachedQuery, nspace::hash_compare<irc::string> > dnscache; +#endif + +/** + * Error types that class Resolver can emit to its error method. + */ +enum ResolverError +{ + RESOLVER_NOERROR = 0, + RESOLVER_NSDOWN = 1, + RESOLVER_NXDOMAIN = 2, + RESOLVER_NOTREADY = 3, + RESOLVER_BADIP = 4, + RESOLVER_TIMEOUT = 5, + RESLOVER_FORCEUNLOAD = 6 +}; + +/** + * A DNS request + */ +class DNSRequest; + +/** + * A DNS packet header + */ +class DNSHeader; + +/** + * A DNS Resource Record (rr) + */ +struct ResourceRecord; + +/** + * Query and resource record types + */ +enum QueryType +{ + DNS_QUERY_NONE = 0, /* Uninitialized Query */ + DNS_QUERY_A = 1, /* 'A' record: an ipv4 address */ + DNS_QUERY_CNAME = 5, /* 'CNAME' record: An alias */ + DNS_QUERY_PTR = 12, /* 'PTR' record: a hostname */ + DNS_QUERY_AAAA = 28, /* 'AAAA' record: an ipv6 address */ + + DNS_QUERY_PTR4 = 0xFFFD, /* Force 'PTR' to use IPV4 scemantics */ + DNS_QUERY_PTR6 = 0xFFFE /* Force 'PTR' to use IPV6 scemantics */ +}; + +#ifdef IPV6 +const QueryType DNS_QUERY_FORWARD = DNS_QUERY_AAAA; +#else +const QueryType DNS_QUERY_FORWARD = DNS_QUERY_A; +#endif +const QueryType DNS_QUERY_REVERSE = DNS_QUERY_PTR; +/** + * Used internally to force PTR lookups to use a certain protocol scemantics, + * e.g. x.x.x.x.in-addr.arpa for v4, and *.ip6.arpa for v6. + */ +enum ForceProtocol +{ + PROTOCOL_IPV4 = 0, /* Forced to use ipv4 */ + PROTOCOL_IPV6 = 1 /* Forced to use ipv6 */ +}; + +/** + * The Resolver class is a high-level abstraction for resolving DNS entries. + * It can do forward and reverse IPv4 lookups, and where IPv6 is supported, will + * also be able to do those, transparent of protocols. Module developers must + * extend this class via inheritence, and then insert a pointer to their derived + * class into the core using Server::AddResolver(). Once you have done this, + * the class will be able to receive callbacks. There are two callbacks which + * can occur by calling virtual methods, one is a success situation, and the other + * an error situation. + */ +class CoreExport Resolver : public Extensible +{ + protected: + /** + * Pointer to creator + */ + InspIRCd* ServerInstance; + /** + * Pointer to creator module (if any, or NULL) + */ + Module* Creator; + /** + * The input data, either a host or an IP address + */ + std::string input; + /** + * True if a forward lookup is being performed, false if otherwise + */ + QueryType querytype; + /** + * The DNS erver being used for lookups. If this is an empty string, + * the value of ServerConfig::DNSServer is used instead. + */ + std::string server; + /** + * The ID allocated to your lookup. This is a pseudo-random number + * between 0 and 65535, a value of -1 indicating a failure. + * The core uses this to route results to the correct objects. + */ + int myid; + + /** + * Cached result, if there is one + */ + CachedQuery *CQ; + + /** + * Time left before cache expiry + */ + int time_left; + public: + /** + * Initiate DNS lookup. Your class should not attempt to delete or free these + * objects, as the core will do this for you. They must always be created upon + * the heap using new, as you cannot be sure at what time they will be deleted. + * Allocating them on the stack or attempting to delete them yourself could cause + * the object to go 'out of scope' and cause a segfault in the core if the result + * arrives at a later time. + * @param source The IP or hostname to resolve + * @param qt The query type to perform. If you just want to perform a forward + * or reverse lookup, and you don't care wether you get ipv4 or ipv6, then use + * the constants DNS_QUERY_FORWARD and DNS_QUERY_REVERSE, which automatically + * select from 'A' record or 'AAAA' record lookups. However, if you want to resolve + * a specific record type, resolution of 'A', 'AAAA', 'PTR' and 'CNAME' records + * is supported. Use one of the QueryType enum values to initiate this type of + * lookup. Resolution of 'AAAA' ipv6 records is always supported, regardless of + * wether InspIRCd is built with ipv6 support. + * If you attempt to resolve a 'PTR' record using DNS_QUERY_PTR, and InspIRCd is + * built with ipv6 support, the 'PTR' record will be formatted to ipv6 specs, + * e.g. x.x.x.x.x....ip6.arpa. otherwise it will be formatted to ipv4 specs, + * e.g. x.x.x.x.in-addr.arpa. This translation is automatic. + * To get around this automatic behaviour, you must use one of the values + * DNS_QUERY_PTR4 or DNS_QUERY_PTR6 to force ipv4 or ipv6 behaviour on the lookup, + * irrespective of what protocol InspIRCd has been built for. + * @param cached The constructor will set this boolean to true or false depending + * on whether the DNS lookup you are attempting is cached (and not expired) or not. + * If the value is cached, upon return this will be set to true, otherwise it will + * be set to false. You should pass this value to InspIRCd::AddResolver(), which + * will then influence the behaviour of the method and determine whether a cached + * or non-cached result is obtained. The value in this variable is always correct + * for the given request when the constructor exits. + * @param creator See the note below. + * @throw ModuleException This class may throw an instance of ModuleException, in the + * event a lookup could not be allocated, or a similar hard error occurs such as + * the network being down. This will also be thrown if an invalid IP address is + * passed when resolving a 'PTR' record. + * + * NOTE: If you are instantiating your DNS lookup from a module, you should set the + * value of creator to point at your Module class. This way if your module is unloaded + * whilst lookups are in progress, they can be safely removed and your module will not + * crash the server. + */ + Resolver(InspIRCd* Instance, const std::string &source, QueryType qt, bool &cached, Module* creator = NULL); + + /** + * The default destructor does nothing. + */ + virtual ~Resolver(); + /** + * When your lookup completes, this method will be called. + * @param result The resulting DNS lookup, either an IP address or a hostname. + * @param ttl The time-to-live value of the result, in the instance of a cached + * result, this is the number of seconds remaining before refresh/expiry. + * @param cached True if the result is a cached result, false if it was requested + * from the DNS server. + */ + virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached) = 0; + /** + * If an error occurs (such as NXDOMAIN, no domain name found) then this method + * will be called. + * @param e A ResolverError enum containing the error type which has occured. + * @param errormessage The error text of the error that occured. + */ + virtual void OnError(ResolverError e, const std::string &errormessage); + /** + * Returns the id value of this class. This is primarily used by the core + * to determine where in various tables to place a pointer to your class, but it + * is safe to call and use this method. + * As specified in RFC1035, each dns request has a 16 bit ID value, ranging + * from 0 to 65535. If there is an issue and the core cannot send your request, + * this method will return -1. + */ + int GetId(); + /** + * Returns the creator module, or NULL + */ + Module* GetCreator(); + /** + * If the result is a cached result, this triggers the objects + * OnLookupComplete. This is done because it is not safe to call + * the abstract virtual method from the constructor. + */ + void TriggerCachedResult(); +}; + +/** DNS is a singleton class used by the core to dispatch dns + * requests to the dns server, and route incoming dns replies + * back to Resolver objects, based upon the request ID. You + * should never use this class yourself. + */ +class CoreExport DNS : public EventHandler +{ + private: + + /** + * Creator/Owner object + */ + InspIRCd* ServerInstance; + + /** + * The maximum value of a dns request id, + * 16 bits wide, 0xFFFF. + */ + static const int MAX_REQUEST_ID = 0xFFFF; + + /** + * A counter used to form part of the pseudo-random id + */ + int currid; + + /** + * We have to turn off a few checks on received packets + * when people are using 4in6 (e.g. ::ffff:xxxx). This is + * a temporary kludge, Please let me know if you know how + * to fix it. + */ + bool ip6munge; + + /** + * Currently cached items + */ + dnscache* cache; + + /** A timer which ticks every hour to remove expired + * items from the DNS cache. + */ + class CacheTimer* PruneTimer; + + /** + * Build a dns packet payload + */ + int MakePayload(const char* name, const QueryType rr, const unsigned short rr_class, unsigned char* payload); + + public: + + /** + * Server address being used currently + */ + int socketfamily; +#ifdef IPV6 + in6_addr myserver6; +#endif + in_addr myserver4; + + /** + * Currently active Resolver classes + */ + Resolver* Classes[MAX_REQUEST_ID]; + + /** + * Requests that are currently 'in flight' + */ + DNSRequest* requests[MAX_REQUEST_ID]; + + /** + * The port number DNS requests are made on, + * and replies have as a source-port number. + */ + static const int QUERY_PORT = 53; + + /** + * Fill an rr (resource record) with data from input + */ + static void FillResourceRecord(ResourceRecord* rr, const unsigned char* input); + + /** + * Fill a header with data from input limited by a length + */ + static void FillHeader(DNSHeader *header, const unsigned char *input, const int length); + + /** + * Empty out a header into a data stream ready for transmission "on the wire" + */ + static void EmptyHeader(unsigned char *output, const DNSHeader *header, const int length); + + /** + * Start the lookup of an ipv4 from a hostname + */ + int GetIP(const char* name); + + /** + * Start the lookup of a hostname from an ip, + * always using the protocol inspircd is built for, + * e.g. use ipv6 reverse lookup when built for ipv6, + * or ipv4 lookup when built for ipv4. + */ + int GetName(const insp_inaddr* ip); + + /** + * Start lookup of a hostname from an ip, but + * force a specific protocol to be used for the lookup + * for example to perform an ipv6 reverse lookup. + */ + int GetNameForce(const char *ip, ForceProtocol fp); + + /** + * Start lookup of an ipv6 from a hostname + */ + int GetIP6(const char *name); + + /** + * Start lookup of a CNAME from another hostname + */ + int GetCName(const char* alias); + + /** + * Fetch the result string (an ip or host) + * and/or an error message to go with it. + */ + DNSResult GetResult(); + + /** + * Handle a SocketEngine read event + * Inherited from EventHandler + */ + void HandleEvent(EventType et, int errornum = 0); + + /** + * Add a Resolver* to the list of active classes + */ + bool AddResolverClass(Resolver* r); + + /** + * Add a query to the list to be sent + */ + DNSRequest* AddQuery(DNSHeader *header, int &id, const char* original); + + /** + * The constructor initialises the dns socket, + * and clears the request lists. + */ + DNS(InspIRCd* Instance); + + /** + * Re-initialize the DNS subsystem. + */ + void Rehash(); + + /** + * Destructor + */ + ~DNS(); + + /** Portable random number generator, generates + * its random number from the ircd stats counters, + * effective user id, time of day and the rollover + * counter (currid) + */ + unsigned long PRNG(); + + /** + * Turn an in6_addr into a .ip6.arpa domain + */ + static void MakeIP6Int(char* query, const in6_addr *ip); + + /** + * Clean out all dns resolvers owned by a particular + * module, to make unloading a module safe if there + * are dns requests currently in progress. + */ + void CleanResolvers(Module* module); + + /** Return the cached value of an IP or hostname + * @param source An IP or hostname to find in the cache. + * @return A pointer to a CachedQuery if the item exists, + * otherwise NULL. + */ + CachedQuery* GetCache(const std::string &source); + + /** Delete a cached item from the DNS cache. + * @param source An IP or hostname to remove + */ + void DelCache(const std::string &source); + + /** Clear all items from the DNS cache immediately. + */ + int ClearCache(); + + /** Prune the DNS cache, e.g. remove all expired + * items and rehash the cache buckets, but leave + * items in the hash which are still valid. + */ + int PruneCache(); +}; + +#endif + diff --git a/include/dynamic.h b/include/dynamic.h index 8f0f9e132..db46291c4 100644 --- a/include/dynamic.h +++ b/include/dynamic.h @@ -1 +1,127 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __DLL_H
#define __DLL_H
/** This typedef represents the init_module function within each module.
* The init_module function is the only exported extern "C" declaration
* in any module file.
*/
typedef void * (initfunc) (void);
#include "inspircd_config.h"
class InspIRCd;
/** The DLLManager class is able to load a module file by filename,
* and locate its init_module symbol.
*/
class CoreExport DLLManager
{
public:
/** This constructor loads the module using dlopen()
* @param ServerInstance The creator class of this object
* @param fname The filename to load. This should be within
* the modules dir.
*/
DLLManager(InspIRCd* ServerInstance, const char *fname);
virtual ~DLLManager();
/** Get a symbol using dynamic linking.
* @param v A function pointer, pointing at an init_module function
* @param sym_name The symbol name to find, usually "init_module"
* @return true if the symbol can be found, also the symbol will be put into v.
*/
bool GetSymbol(void **v, const char *sym_name);
/** Get the last error from dlopen() or dlsym().
* @return The last error string, or NULL if no error has occured.
*/
char* LastError()
{
return err;
}
/** The module handle.
* This is OS dependent, on POSIX platforms it is a pointer to a function
* pointer (yes, really!) and on windows it is a library handle.
*/
void *h;
protected:
/** The last error string, or NULL
*/
char *err;
};
/** This class is a specialized form of DLLManager designed to load InspIRCd modules.
* It's job is to call the init_module function and receive a factory pointer.
*/
class CoreExport DLLFactoryBase : public DLLManager
{
public:
/** Default constructor.
* This constructor loads a module file by calling its DLLManager subclass constructor,
* then finds the symbol using DLLManager::GetSymbol(), and calls the symbol,
* obtaining a valid pointer to the init_module function
*/
DLLFactoryBase(InspIRCd* Instance, const char *fname, const char *func_name = 0);
/** Default destructor.
*/
virtual ~DLLFactoryBase();
/** A function pointer to the factory function.
*/
void * (*factory_func)(void);
};
/** This is the highest-level class of the DLLFactory system used to load InspIRCd modules.
* Its job is to finally call the init_module function and obtain a pointer to a ModuleFactory.
* This template is a container for ModuleFactory itself, so that it may 'plug' into ModuleFactory
* and provide module loading capabilities transparently.
*/
template <class T> class CoreExport DLLFactory : public DLLFactoryBase
{
public:
/** Default constructor.
* This constructor passes its paramerers down through DLLFactoryBase and then DLLManager
* to load the module, then calls the factory function to retrieve a pointer to a ModuleFactory
* class. It is then down to the core to call the ModuleFactory::CreateModule() method and
* receive a Module* which it can insert into its module lists.
*/
DLLFactory(InspIRCd* Instance, const char *fname, const char *func_name=0) : DLLFactoryBase(Instance, fname, func_name)
{
if (factory_func)
factory = reinterpret_cast<T*>(factory_func());
else
factory = reinterpret_cast<T*>(-1);
}
/** The destructor deletes the ModuleFactory pointer.
*/
~DLLFactory()
{
if (factory)
delete factory;
}
/** The ModuleFactory pointer.
*/
T *factory;
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __DLL_H +#define __DLL_H + +/** This typedef represents the init_module function within each module. + * The init_module function is the only exported extern "C" declaration + * in any module file. + */ +typedef void * (initfunc) (void); + +#include "inspircd_config.h" + +class InspIRCd; + +/** The DLLManager class is able to load a module file by filename, + * and locate its init_module symbol. + */ +class CoreExport DLLManager +{ + public: + /** This constructor loads the module using dlopen() + * @param ServerInstance The creator class of this object + * @param fname The filename to load. This should be within + * the modules dir. + */ + DLLManager(InspIRCd* ServerInstance, const char *fname); + virtual ~DLLManager(); + + /** Get a symbol using dynamic linking. + * @param v A function pointer, pointing at an init_module function + * @param sym_name The symbol name to find, usually "init_module" + * @return true if the symbol can be found, also the symbol will be put into v. + */ + bool GetSymbol(void **v, const char *sym_name); + + /** Get the last error from dlopen() or dlsym(). + * @return The last error string, or NULL if no error has occured. + */ + char* LastError() + { + return err; + } + + /** The module handle. + * This is OS dependent, on POSIX platforms it is a pointer to a function + * pointer (yes, really!) and on windows it is a library handle. + */ + void *h; + + protected: + + /** The last error string, or NULL + */ + char *err; +}; + +/** This class is a specialized form of DLLManager designed to load InspIRCd modules. + * It's job is to call the init_module function and receive a factory pointer. + */ +class CoreExport DLLFactoryBase : public DLLManager +{ + public: + /** Default constructor. + * This constructor loads a module file by calling its DLLManager subclass constructor, + * then finds the symbol using DLLManager::GetSymbol(), and calls the symbol, + * obtaining a valid pointer to the init_module function + */ + DLLFactoryBase(InspIRCd* Instance, const char *fname, const char *func_name = 0); + + /** Default destructor. + */ + virtual ~DLLFactoryBase(); + + /** A function pointer to the factory function. + */ + void * (*factory_func)(void); +}; + +/** This is the highest-level class of the DLLFactory system used to load InspIRCd modules. + * Its job is to finally call the init_module function and obtain a pointer to a ModuleFactory. + * This template is a container for ModuleFactory itself, so that it may 'plug' into ModuleFactory + * and provide module loading capabilities transparently. + */ +template <class T> class CoreExport DLLFactory : public DLLFactoryBase +{ + public: + /** Default constructor. + * This constructor passes its paramerers down through DLLFactoryBase and then DLLManager + * to load the module, then calls the factory function to retrieve a pointer to a ModuleFactory + * class. It is then down to the core to call the ModuleFactory::CreateModule() method and + * receive a Module* which it can insert into its module lists. + */ + DLLFactory(InspIRCd* Instance, const char *fname, const char *func_name=0) : DLLFactoryBase(Instance, fname, func_name) + { + if (factory_func) + factory = reinterpret_cast<T*>(factory_func()); + else + factory = reinterpret_cast<T*>(-1); + } + + /** The destructor deletes the ModuleFactory pointer. + */ + ~DLLFactory() + { + if (factory) + delete factory; + } + + /** The ModuleFactory pointer. + */ + T *factory; +}; + +#endif + diff --git a/include/exitcodes.h b/include/exitcodes.h index 84132c5ca..d68301984 100644 --- a/include/exitcodes.h +++ b/include/exitcodes.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __EXITCODE_H__
#define __EXITCODE_H__
/** Valid exit codes to be used with InspIRCd::Exit()
*/
enum ExitStatus
{
EXIT_STATUS_NOERROR = 0, /* No error */
EXIT_STATUS_DIE = 1, /* Operator issued DIE */
EXIT_STATUS_FAILED_EXEC = 2, /* execv() failed */
EXIT_STATUS_INTERNAL = 3, /* Internal error */
EXIT_STATUS_CONFIG = 4, /* Config error */
EXIT_STATUS_LOG = 5, /* Log file error */
EXIT_STATUS_FORK = 6, /* fork() failed */
EXIT_STATUS_ARGV = 7, /* Invalid program arguments */
EXIT_STATUS_BIND = 8, /* Port binding failed on all ports */
EXIT_STATUS_PID = 9, /* Couldn't write PID file */
EXIT_STATUS_SOCKETENGINE = 10, /* Couldn't start socket engine */
EXIT_STATUS_ROOT = 11, /* Refusing to start as root */
EXIT_STATUS_DIETAG = 12, /* Found a die tag in the config file */
EXIT_STATUS_MODULE = 13, /* Couldn't load a required module */
EXIT_STATUS_CREATEPROCESS = 14, /* CreateProcess failed (windows) */
EXIT_STATUS_SIGTERM = 15 /* Note: dont move this value. It corresponds with the value of #define SIGTERM. */
};
/** Array that maps exit codes (ExitStatus types) to
* human-readable strings to be shown on shutdown.
*/
extern const char * ExitCodes[];
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __EXITCODE_H__ +#define __EXITCODE_H__ + +/** Valid exit codes to be used with InspIRCd::Exit() + */ +enum ExitStatus +{ + EXIT_STATUS_NOERROR = 0, /* No error */ + EXIT_STATUS_DIE = 1, /* Operator issued DIE */ + EXIT_STATUS_FAILED_EXEC = 2, /* execv() failed */ + EXIT_STATUS_INTERNAL = 3, /* Internal error */ + EXIT_STATUS_CONFIG = 4, /* Config error */ + EXIT_STATUS_LOG = 5, /* Log file error */ + EXIT_STATUS_FORK = 6, /* fork() failed */ + EXIT_STATUS_ARGV = 7, /* Invalid program arguments */ + EXIT_STATUS_BIND = 8, /* Port binding failed on all ports */ + EXIT_STATUS_PID = 9, /* Couldn't write PID file */ + EXIT_STATUS_SOCKETENGINE = 10, /* Couldn't start socket engine */ + EXIT_STATUS_ROOT = 11, /* Refusing to start as root */ + EXIT_STATUS_DIETAG = 12, /* Found a die tag in the config file */ + EXIT_STATUS_MODULE = 13, /* Couldn't load a required module */ + EXIT_STATUS_CREATEPROCESS = 14, /* CreateProcess failed (windows) */ + EXIT_STATUS_SIGTERM = 15 /* Note: dont move this value. It corresponds with the value of #define SIGTERM. */ +}; + +/** Array that maps exit codes (ExitStatus types) to + * human-readable strings to be shown on shutdown. + */ +extern const char * ExitCodes[]; + +#endif + diff --git a/include/globals.h b/include/globals.h index 5755c1fd0..4a01e454e 100644 --- a/include/globals.h +++ b/include/globals.h @@ -1 +1,39 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __WORLD_H
#define __WORLD_H
#include <string>
#include <deque>
#include <map>
#include <vector>
/** A cached text file stored with its contents as lines
*/
typedef std::deque<std::string> file_cache;
/** A configuration key and value pair
*/
typedef std::pair< std::string, std::string > KeyVal;
/** A list of related configuration keys and values
*/
typedef std::vector< KeyVal > KeyValList;
/** An entire config file, built up of KeyValLists
*/
typedef std::multimap< std::string, KeyValList > ConfigDataHash;
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __WORLD_H +#define __WORLD_H + +#include <string> +#include <deque> +#include <map> +#include <vector> + +/** A cached text file stored with its contents as lines + */ +typedef std::deque<std::string> file_cache; + +/** A configuration key and value pair + */ +typedef std::pair< std::string, std::string > KeyVal; + +/** A list of related configuration keys and values + */ +typedef std::vector< KeyVal > KeyValList; + +/** An entire config file, built up of KeyValLists + */ +typedef std::multimap< std::string, KeyValList > ConfigDataHash; + +#endif + diff --git a/include/hash_map.h b/include/hash_map.h index 36e0b2b02..784a8bc3b 100644 --- a/include/hash_map.h +++ b/include/hash_map.h @@ -1 +1,33 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef INSPIRCD_HASHMAP_H
#define INSPIRCD_HASHMAP_H
#include "inspircd_config.h"
/** Where hash_map is varies from compiler to compiler
* as it is not standard.
*/
#ifndef WIN32
#include <ext/hash_map>
/** Oddball linux namespace for hash_map */
#define nspace __gnu_cxx
#else
#include <hash_map>
#define nspace stdext
/** Oddball windows namespace for hash_map */
using stdext::hash_map;
#endif
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef INSPIRCD_HASHMAP_H +#define INSPIRCD_HASHMAP_H + +#include "inspircd_config.h" + +/** Where hash_map is varies from compiler to compiler + * as it is not standard. + */ +#ifndef WIN32 +#include <ext/hash_map> +/** Oddball linux namespace for hash_map */ +#define nspace __gnu_cxx +#else +#include <hash_map> +#define nspace stdext +/** Oddball windows namespace for hash_map */ +using stdext::hash_map; +#endif + +#endif diff --git a/include/hashcomp.h b/include/hashcomp.h index 47f051c80..0556f4399 100644 --- a/include/hashcomp.h +++ b/include/hashcomp.h @@ -1 +1,710 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef _HASHCOMP_H_
#define _HASHCOMP_H_
#include "inspircd_config.h"
#include "socket.h"
#include "hash_map.h"
/*******************************************************
* This file contains classes and templates that deal
* with the comparison and hashing of 'irc strings'.
* An 'irc string' is a string which compares in a
* case insensitive manner, and as per RFC 1459 will
* treat [ identical to {, ] identical to }, and \
* as identical to |.
*
* Our hashing functions are designed to accept
* std::string and compare/hash them as type irc::string
* by converting them internally. This makes them
* backwards compatible with other code which is not
* aware of irc::string.
*******************************************************/
/** Required namespaces and symbols */
using namespace std;
/** aton() */
using irc::sockets::insp_aton;
/** nota() */
using irc::sockets::insp_ntoa;
#ifndef LOWERMAP
#define LOWERMAP
/** A mapping of uppercase to lowercase, including scandinavian
* 'oddities' as specified by RFC1459, e.g. { -> [, and | -> \
*/
unsigned const char lowermap[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 0-19 */
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, /* 20-39 */
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, /* 40-59 */
60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, /* 60-79 */
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 94, 95, 96, 97, 98, 99, /* 80-99 */
100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, /* 100-119 */
120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, /* 120-139 */
140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, /* 140-159 */
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, /* 160-179 */
180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, /* 180-199 */
200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, /* 200-219 */
220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, /* 220-239 */
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 /* 240-255 */
};
#endif
/** The irc namespace contains a number of helper classes.
*/
namespace irc
{
/** This class returns true if two strings match.
* Case sensitivity is ignored, and the RFC 'character set'
* is adhered to
*/
struct StrHashComp
{
/** The operator () does the actual comparison in hash_map
*/
bool operator()(const std::string& s1, const std::string& s2) const;
};
/** The irc_char_traits class is used for RFC-style comparison of strings.
* This class is used to implement irc::string, a case-insensitive, RFC-
* comparing string class.
*/
struct irc_char_traits : std::char_traits<char> {
/** Check if two chars match.
* @param c1st First character
* @param c2nd Second character
* @return true if the characters are equal
*/
static bool eq(char c1st, char c2nd);
/** Check if two chars do NOT match.
* @param c1st First character
* @param c2nd Second character
* @return true if the characters are unequal
*/
static bool ne(char c1st, char c2nd);
/** Check if one char is less than another.
* @param c1st First character
* @param c2nd Second character
* @return true if c1st is less than c2nd
*/
static bool lt(char c1st, char c2nd);
/** Compare two strings of size n.
* @param str1 First string
* @param str2 Second string
* @param n Length to compare to
* @return similar to strcmp, zero for equal, less than zero for str1
* being less and greater than zero for str1 being greater than str2.
*/
static CoreExport int compare(const char* str1, const char* str2, size_t n);
/** Find a char within a string up to position n.
* @param s1 String to find in
* @param n Position to search up to
* @param c Character to search for
* @return Pointer to the first occurance of c in s1
*/
static CoreExport const char* find(const char* s1, int n, char c);
};
/** Compose a hex string from raw data.
* @param raw The raw data to compose hex from
* @pram rawsz The size of the raw data buffer
* @return The hex string.
*/
CoreExport std::string hex(const unsigned char *raw, size_t rawsz);
/** This typedef declares irc::string based upon irc_char_traits.
*/
typedef basic_string<char, irc_char_traits, allocator<char> > string;
/** irc::stringjoiner joins string lists into a string, using
* the given seperator string.
* This class can join a vector of std::string, a deque of
* std::string, or a const char** array, using overloaded
* constructors.
*/
class CoreExport stringjoiner
{
private:
/** Output string
*/
std::string joined;
public:
/** Join elements of a vector, between (and including) begin and end
* @param seperator The string to seperate values with
* @param sequence One or more items to seperate
* @param begin The starting element in the sequence to be joined
* @param end The ending element in the sequence to be joined
*/
stringjoiner(const std::string &seperator, const std::vector<std::string> &sequence, int begin, int end);
/** Join elements of a deque, between (and including) begin and end
* @param seperator The string to seperate values with
* @param sequence One or more items to seperate
* @param begin The starting element in the sequence to be joined
* @param end The ending element in the sequence to be joined
*/
stringjoiner(const std::string &seperator, const std::deque<std::string> &sequence, int begin, int end);
/** Join elements of an array of char arrays, between (and including) begin and end
* @param seperator The string to seperate values with
* @param sequence One or more items to seperate
* @param begin The starting element in the sequence to be joined
* @param end The ending element in the sequence to be joined
*/
stringjoiner(const std::string &seperator, const char** sequence, int begin, int end);
/** Get the joined sequence
* @return A reference to the joined string
*/
std::string& GetJoined();
};
/** irc::modestacker stacks mode sequences into a list.
* It can then reproduce this list, clamped to a maximum of MAXMODES
* values per line.
*/
class CoreExport modestacker
{
private:
/** The mode sequence and its parameters
*/
std::deque<std::string> sequence;
/** True if the mode sequence is initially adding
* characters, false if it is initially removing
* them
*/
bool adding;
public:
/** Construct a new modestacker.
* @param add True if the stack is adding modes,
* false if it is removing them
*/
modestacker(bool add);
/** Push a modeletter and its parameter onto the stack.
* No checking is performed as to if this mode actually
* requires a parameter. If you stack invalid mode
* sequences, they will be tidied if and when they are
* passed to a mode parser.
* @param modeletter The mode letter to insert
* @param parameter The parameter for the mode
*/
void Push(char modeletter, const std::string ¶meter);
/** Push a modeletter without parameter onto the stack.
* No checking is performed as to if this mode actually
* requires a parameter. If you stack invalid mode
* sequences, they will be tidied if and when they are
* passed to a mode parser.
* @param modeletter The mode letter to insert
*/
void Push(char modeletter);
/** Push a '+' symbol onto the stack.
*/
void PushPlus();
/** Push a '-' symbol onto the stack.
*/
void PushMinus();
/** Return zero or more elements which form the
* mode line. This will be clamped to a max of
* MAXMODES items (MAXMODES-1 mode parameters and
* one mode sequence string), and max_line_size
* characters. As specified below, this function
* should be called in a loop until it returns zero,
* indicating there are no more modes to return.
* @param result The deque to populate. This will
* be cleared before it is used.
* @param max_line_size The maximum size of the line
* to build, in characters, seperate to MAXMODES.
* @return The number of elements in the deque.
* The function should be called repeatedly until it
* returns 0, in case there are multiple lines of
* mode changes to be obtained.
*/
int GetStackedLine(std::deque<std::string> &result, int max_line_size = 360);
};
/** irc::tokenstream reads a string formatted as per RFC1459 and RFC2812.
* It will split the string into 'tokens' each containing one parameter
* from the string.
* For instance, if it is instantiated with the string:
* "PRIVMSG #test :foo bar baz qux"
* then each successive call to tokenstream::GetToken() will return
* "PRIVMSG", "#test", "foo bar baz qux", "".
* Note that if the whole string starts with a colon this is not taken
* to mean the string is all one parameter, and the first item in the
* list will be ":item". This is to allow for parsing 'source' fields
* from data.
*/
class CoreExport tokenstream
{
private:
/** Original string
*/
std::string tokens;
/** Last position of a seperator token
*/
std::string::iterator last_starting_position;
/** Current string position
*/
std::string::iterator n;
/** True if the last value was an ending value
*/
bool last_pushed;
public:
/** Create a tokenstream and fill it with the provided data
*/
tokenstream(const std::string &source);
~tokenstream();
/** Fetch the next token from the stream as a std::string
* @param token The next token available, or an empty string if none remain
* @return True if tokens are left to be read, false if the last token was just retrieved.
*/
bool GetToken(std::string &token);
/** Fetch the next token from the stream as an irc::string
* @param token The next token available, or an empty string if none remain
* @return True if tokens are left to be read, false if the last token was just retrieved.
*/
bool GetToken(irc::string &token);
/** Fetch the next token from the stream as an integer
* @param token The next token available, or undefined if none remain
* @return True if tokens are left to be read, false if the last token was just retrieved.
*/
bool GetToken(int &token);
/** Fetch the next token from the stream as a long integer
* @param token The next token available, or undefined if none remain
* @return True if tokens are left to be read, false if the last token was just retrieved.
*/
bool GetToken(long &token);
};
/** irc::sepstream allows for splitting token seperated lists.
* Each successive call to sepstream::GetToken() returns
* the next token, until none remain, at which point the method returns
* an empty string.
*/
class CoreExport sepstream : public classbase
{
private:
/** Original string.
*/
std::string tokens;
/** Last position of a seperator token
*/
std::string::iterator last_starting_position;
/** Current string position
*/
std::string::iterator n;
/** Seperator value
*/
char sep;
public:
/** Create a sepstream and fill it with the provided data
*/
sepstream(const std::string &source, char seperator);
virtual ~sepstream();
/** Fetch the next token from the stream
* @return The next token is returned, or an empty string if none remain
*/
virtual const std::string GetToken();
/** Fetch the entire remaining stream, without tokenizing
* @return The remaining part of the stream
*/
virtual const std::string GetRemaining();
/** Returns true if the end of the stream has been reached
* @return True if the end of the stream has been reached, otherwise false
*/
virtual bool StreamEnd();
};
/** A derived form of sepstream, which seperates on commas
*/
class CoreExport commasepstream : public sepstream
{
public:
/** Initialize with comma seperator
*/
commasepstream(const std::string &source) : sepstream(source, ',')
{
}
};
/** A derived form of sepstream, which seperates on spaces
*/
class CoreExport spacesepstream : public sepstream
{
public:
/** Initialize with space seperator
*/
spacesepstream(const std::string &source) : sepstream(source, ' ')
{
}
};
/** The portparser class seperates out a port range into integers.
* A port range may be specified in the input string in the form
* "6660,6661,6662-6669,7020". The end of the stream is indicated by
* a return value of 0 from portparser::GetToken(). If you attempt
* to specify an illegal range (e.g. one where start >= end, or
* start or end < 0) then GetToken() will return the first element
* of the pair of numbers.
*/
class CoreExport portparser : public classbase
{
private:
/** Used to split on commas
*/
commasepstream* sep;
/** Current position in a range of ports
*/
long in_range;
/** Starting port in a range of ports
*/
long range_begin;
/** Ending port in a range of ports
*/
long range_end;
/** Allow overlapped port ranges
*/
bool overlapped;
/** Used to determine overlapping of ports
* without O(n) algorithm being used
*/
std::map<long, bool> overlap_set;
/** Returns true if val overlaps an existing range
*/
bool Overlaps(long val);
public:
/** Create a portparser and fill it with the provided data
* @param source The source text to parse from
* @param allow_overlapped Allow overlapped ranges
*/
portparser(const std::string &source, bool allow_overlapped = true);
/** Frees the internal commasepstream object
*/
~portparser();
/** Fetch the next token from the stream
* @return The next port number is returned, or 0 if none remain
*/
long GetToken();
};
/** Used to hold a bitfield definition in dynamicbitmask.
* You must be allocated one of these by dynamicbitmask::Allocate(),
* you should not fill the values yourself!
*/
typedef std::pair<size_t, unsigned char> bitfield;
/** The irc::dynamicbitmask class is used to maintain a bitmap of
* boolean values, which can grow to any reasonable size no matter
* how many bitfields are in it.
*
* It starts off at 32 bits in size, large enough to hold 32 boolean
* values, with a memory allocation of 8 bytes. If you allocate more
* than 32 bits, the class will grow the bitmap by 8 bytes at a time
* for each set of 8 bitfields you allocate with the Allocate()
* method.
*
* This method is designed so that multiple modules can be allocated
* bit values in a bitmap dynamically, rather than having to define
* costs in a fixed size unsigned integer and having the possibility
* of collisions of values in different third party modules.
*
* IMPORTANT NOTE:
*
* To use this class, you must derive from it.
* This is because each derived instance has its own freebits array
* which can determine what bitfields are allocated on a TYPE BY TYPE
* basis, e.g. an irc::dynamicbitmask type for userrecs, and one for
* chanrecs, etc. You should inheret it in a very simple way as follows.
* The base class will resize and maintain freebits as required, you are
* just required to make the pointer static and specific to this class
* type.
*
* \code
* class mydbitmask : public irc::dynamicbitmask
* {
* private:
*
* static unsigned char* freebits;
*
* public:
*
* mydbitmask() : irc::dynamicbitmask()
* {
* freebits = new unsigned char[this->bits_size];
* memset(freebits, 0, this->bits_size);
* }
*
* ~mydbitmask()
* {
* delete[] freebits;
* }
*
* unsigned char* GetFreeBits()
* {
* return freebits;
* }
*
* void SetFreeBits(unsigned char* freebt)
* {
* freebits = freebt;
* }
* };
* \endcode
*/
class CoreExport dynamicbitmask : public classbase
{
private:
/** Data bits. We start with four of these,
* and we grow the bitfield as we allocate
* more than 32 entries with Allocate().
*/
unsigned char* bits;
protected:
/** Current set size (size of freebits and bits).
* Both freebits and bits will ALWAYS be the
* same length.
*/
unsigned char bits_size;
public:
/** Allocate the initial memory for bits and
* freebits and zero the memory.
*/
dynamicbitmask();
/** Free the memory used by bits and freebits
*/
virtual ~dynamicbitmask();
/** Allocate an irc::bitfield.
* @return An irc::bitfield which can be used
* with Get, Deallocate and Toggle methods.
* @throw Can throw std::bad_alloc if there is
* no ram left to grow the bitmask.
*/
bitfield Allocate();
/** Deallocate an irc::bitfield.
* @param An irc::bitfield to deallocate.
* @return True if the bitfield could be
* deallocated, false if it could not.
*/
bool Deallocate(bitfield &pos);
/** Toggle the value of a bitfield.
* @param pos A bitfield to allocate, previously
* allocated by dyamicbitmask::Allocate().
* @param state The state to set the field to.
*/
void Toggle(bitfield &pos, bool state);
/** Get the value of a bitfield.
* @param pos A bitfield to retrieve, previously
* allocated by dyamicbitmask::Allocate().
* @return The value of the bitfield.
* @throw Will throw ModuleException if the bitfield
* you provide is outside of the range
* 0 >= bitfield.first < size_bits.
*/
bool Get(bitfield &pos);
/** Return the size in bytes allocated to the bits
* array.
* Note that the actual allocation is twice this,
* as there are an equal number of bytes allocated
* for the freebits array.
*/
unsigned char GetSize();
/** Get free bits mask
*/
virtual unsigned char* GetFreeBits() { return NULL; }
/** Set free bits mask
*/
virtual void SetFreeBits(unsigned char* freebits) { }
};
/** Turn _ characters in a string into spaces
* @param n String to translate
* @return The new value with _ translated to space.
*/
CoreExport const char* Spacify(const char* n);
}
/* Define operators for using >> and << with irc::string to an ostream on an istream. */
/* This was endless fun. No. Really. */
/* It was also the first core change Ommeh made, if anyone cares */
/** Operator << for irc::string
*/
inline std::ostream& operator<<(std::ostream &os, const irc::string &str) { return os << str.c_str(); }
/** Operator >> for irc::string
*/
inline std::istream& operator>>(std::istream &is, irc::string &str)
{
std::string tmp;
is >> tmp;
str = tmp.c_str();
return is;
}
/* Define operators for + and == with irc::string to std::string for easy assignment
* and comparison
*
* Operator +
*/
inline std::string operator+ (std::string& leftval, irc::string& rightval)
{
return leftval + std::string(rightval.c_str());
}
/* Define operators for + and == with irc::string to std::string for easy assignment
* and comparison
*
* Operator +
*/
inline irc::string operator+ (irc::string& leftval, std::string& rightval)
{
return leftval + irc::string(rightval.c_str());
}
/* Define operators for + and == with irc::string to std::string for easy assignment
* and comparison
*
* Operator ==
*/
inline bool operator== (const std::string& leftval, const irc::string& rightval)
{
return (leftval.c_str() == rightval);
}
/* Define operators for + and == with irc::string to std::string for easy assignment
* and comparison
*
* Operator ==
*/
inline bool operator== (const irc::string& leftval, const std::string& rightval)
{
return (leftval == rightval.c_str());
}
/** Assign an irc::string to a std::string.
*/
inline std::string assign(const irc::string &other) { return other.c_str(); }
/** Assign a std::string to an irc::string.
*/
inline irc::string assign(const std::string &other) { return other.c_str(); }
/** Trim the leading and trailing spaces from a std::string.
*/
inline std::string& trim(std::string &str)
{
std::string::size_type start = str.find_first_not_of(" ");
std::string::size_type end = str.find_last_not_of(" ");
if (start == std::string::npos || end == std::string::npos)
str = "";
else
str = str.substr(start, end-start+1);
return str;
}
/** Hashing stuff is totally different on vc++'s hash_map implementation, so to save a buttload of
* #ifdefs we'll just do it all at once
*/
namespace nspace
{
/** Hashing function to hash irc::string
*/
#ifdef WINDOWS
template<> class CoreExport hash_compare<irc::string, std::less<irc::string> >
{
public:
enum { bucket_size = 4, min_buckets = 8 }; /* Got these numbers from the CRT source, if anyone wants to change them feel free. */
/** Compare two irc::string values for hashing in hash_map
*/
bool operator()(const irc::string & s1, const irc::string & s2) const
{
if(s1.length() != s2.length()) return true;
return (irc::irc_char_traits::compare(s1.c_str(), s2.c_str(), s1.length()) < 0);
}
/** Hash an irc::string value for hash_map
*/
size_t operator()(const irc::string & s) const;
};
template<> class CoreExport hash_compare<std::string, std::less<std::string> >
{
public:
enum { bucket_size = 4, min_buckets = 8 }; /* Again, from the CRT source */
/** Compare two std::string values for hashing in hash_map
*/
bool operator()(const std::string & s1, const std::string & s2) const
{
if(s1.length() != s2.length()) return true;
return (irc::irc_char_traits::compare(s1.c_str(), s2.c_str(), s1.length()) < 0);
}
/** Hash a std::string using RFC1459 case sensitivity rules
* @param s A string to hash
* @return The hash value
*/
size_t operator()(const std::string & s) const;
};
#else
template<> struct hash<irc::string>
{
/** Hash an irc::string using RFC1459 case sensitivity rules
* @param s A string to hash
* @return The hash value
*/
size_t operator()(const irc::string &s) const;
};
template<> struct hash<std::string>
{
/** Hash a std::string using RFC1459 case sensitivity rules
* @param s A string to hash
* @return The hash value
*/
size_t operator()(const string &s) const;
};
#endif
/** Convert a string to lower case respecting RFC1459
* @param n A string to lowercase
*/
void strlower(char *n);
}
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef _HASHCOMP_H_ +#define _HASHCOMP_H_ + +#include "inspircd_config.h" +#include "socket.h" +#include "hash_map.h" + +/******************************************************* + * This file contains classes and templates that deal + * with the comparison and hashing of 'irc strings'. + * An 'irc string' is a string which compares in a + * case insensitive manner, and as per RFC 1459 will + * treat [ identical to {, ] identical to }, and \ + * as identical to |. + * + * Our hashing functions are designed to accept + * std::string and compare/hash them as type irc::string + * by converting them internally. This makes them + * backwards compatible with other code which is not + * aware of irc::string. + *******************************************************/ + +/** Required namespaces and symbols */ +using namespace std; + +/** aton() */ +using irc::sockets::insp_aton; + +/** nota() */ +using irc::sockets::insp_ntoa; + +#ifndef LOWERMAP +#define LOWERMAP +/** A mapping of uppercase to lowercase, including scandinavian + * 'oddities' as specified by RFC1459, e.g. { -> [, and | -> \ + */ +unsigned const char lowermap[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 0-19 */ + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, /* 20-39 */ + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, /* 40-59 */ + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, /* 60-79 */ + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 94, 95, 96, 97, 98, 99, /* 80-99 */ + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, /* 100-119 */ + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, /* 120-139 */ + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, /* 140-159 */ + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, /* 160-179 */ + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, /* 180-199 */ + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, /* 200-219 */ + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, /* 220-239 */ + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 /* 240-255 */ +}; +#endif + +/** The irc namespace contains a number of helper classes. + */ +namespace irc +{ + + /** This class returns true if two strings match. + * Case sensitivity is ignored, and the RFC 'character set' + * is adhered to + */ + struct StrHashComp + { + /** The operator () does the actual comparison in hash_map + */ + bool operator()(const std::string& s1, const std::string& s2) const; + }; + + /** The irc_char_traits class is used for RFC-style comparison of strings. + * This class is used to implement irc::string, a case-insensitive, RFC- + * comparing string class. + */ + struct irc_char_traits : std::char_traits<char> { + + /** Check if two chars match. + * @param c1st First character + * @param c2nd Second character + * @return true if the characters are equal + */ + static bool eq(char c1st, char c2nd); + + /** Check if two chars do NOT match. + * @param c1st First character + * @param c2nd Second character + * @return true if the characters are unequal + */ + static bool ne(char c1st, char c2nd); + + /** Check if one char is less than another. + * @param c1st First character + * @param c2nd Second character + * @return true if c1st is less than c2nd + */ + static bool lt(char c1st, char c2nd); + + /** Compare two strings of size n. + * @param str1 First string + * @param str2 Second string + * @param n Length to compare to + * @return similar to strcmp, zero for equal, less than zero for str1 + * being less and greater than zero for str1 being greater than str2. + */ + static CoreExport int compare(const char* str1, const char* str2, size_t n); + + /** Find a char within a string up to position n. + * @param s1 String to find in + * @param n Position to search up to + * @param c Character to search for + * @return Pointer to the first occurance of c in s1 + */ + static CoreExport const char* find(const char* s1, int n, char c); + }; + + /** Compose a hex string from raw data. + * @param raw The raw data to compose hex from + * @pram rawsz The size of the raw data buffer + * @return The hex string. + */ + CoreExport std::string hex(const unsigned char *raw, size_t rawsz); + + /** This typedef declares irc::string based upon irc_char_traits. + */ + typedef basic_string<char, irc_char_traits, allocator<char> > string; + + /** irc::stringjoiner joins string lists into a string, using + * the given seperator string. + * This class can join a vector of std::string, a deque of + * std::string, or a const char** array, using overloaded + * constructors. + */ + class CoreExport stringjoiner + { + private: + /** Output string + */ + std::string joined; + public: + /** Join elements of a vector, between (and including) begin and end + * @param seperator The string to seperate values with + * @param sequence One or more items to seperate + * @param begin The starting element in the sequence to be joined + * @param end The ending element in the sequence to be joined + */ + stringjoiner(const std::string &seperator, const std::vector<std::string> &sequence, int begin, int end); + /** Join elements of a deque, between (and including) begin and end + * @param seperator The string to seperate values with + * @param sequence One or more items to seperate + * @param begin The starting element in the sequence to be joined + * @param end The ending element in the sequence to be joined + */ + stringjoiner(const std::string &seperator, const std::deque<std::string> &sequence, int begin, int end); + /** Join elements of an array of char arrays, between (and including) begin and end + * @param seperator The string to seperate values with + * @param sequence One or more items to seperate + * @param begin The starting element in the sequence to be joined + * @param end The ending element in the sequence to be joined + */ + stringjoiner(const std::string &seperator, const char** sequence, int begin, int end); + + /** Get the joined sequence + * @return A reference to the joined string + */ + std::string& GetJoined(); + }; + + /** irc::modestacker stacks mode sequences into a list. + * It can then reproduce this list, clamped to a maximum of MAXMODES + * values per line. + */ + class CoreExport modestacker + { + private: + /** The mode sequence and its parameters + */ + std::deque<std::string> sequence; + /** True if the mode sequence is initially adding + * characters, false if it is initially removing + * them + */ + bool adding; + public: + /** Construct a new modestacker. + * @param add True if the stack is adding modes, + * false if it is removing them + */ + modestacker(bool add); + /** Push a modeletter and its parameter onto the stack. + * No checking is performed as to if this mode actually + * requires a parameter. If you stack invalid mode + * sequences, they will be tidied if and when they are + * passed to a mode parser. + * @param modeletter The mode letter to insert + * @param parameter The parameter for the mode + */ + void Push(char modeletter, const std::string ¶meter); + /** Push a modeletter without parameter onto the stack. + * No checking is performed as to if this mode actually + * requires a parameter. If you stack invalid mode + * sequences, they will be tidied if and when they are + * passed to a mode parser. + * @param modeletter The mode letter to insert + */ + void Push(char modeletter); + /** Push a '+' symbol onto the stack. + */ + void PushPlus(); + /** Push a '-' symbol onto the stack. + */ + void PushMinus(); + /** Return zero or more elements which form the + * mode line. This will be clamped to a max of + * MAXMODES items (MAXMODES-1 mode parameters and + * one mode sequence string), and max_line_size + * characters. As specified below, this function + * should be called in a loop until it returns zero, + * indicating there are no more modes to return. + * @param result The deque to populate. This will + * be cleared before it is used. + * @param max_line_size The maximum size of the line + * to build, in characters, seperate to MAXMODES. + * @return The number of elements in the deque. + * The function should be called repeatedly until it + * returns 0, in case there are multiple lines of + * mode changes to be obtained. + */ + int GetStackedLine(std::deque<std::string> &result, int max_line_size = 360); + }; + + /** irc::tokenstream reads a string formatted as per RFC1459 and RFC2812. + * It will split the string into 'tokens' each containing one parameter + * from the string. + * For instance, if it is instantiated with the string: + * "PRIVMSG #test :foo bar baz qux" + * then each successive call to tokenstream::GetToken() will return + * "PRIVMSG", "#test", "foo bar baz qux", "". + * Note that if the whole string starts with a colon this is not taken + * to mean the string is all one parameter, and the first item in the + * list will be ":item". This is to allow for parsing 'source' fields + * from data. + */ + class CoreExport tokenstream + { + private: + /** Original string + */ + std::string tokens; + /** Last position of a seperator token + */ + std::string::iterator last_starting_position; + /** Current string position + */ + std::string::iterator n; + /** True if the last value was an ending value + */ + bool last_pushed; + public: + /** Create a tokenstream and fill it with the provided data + */ + tokenstream(const std::string &source); + ~tokenstream(); + + /** Fetch the next token from the stream as a std::string + * @param token The next token available, or an empty string if none remain + * @return True if tokens are left to be read, false if the last token was just retrieved. + */ + bool GetToken(std::string &token); + + /** Fetch the next token from the stream as an irc::string + * @param token The next token available, or an empty string if none remain + * @return True if tokens are left to be read, false if the last token was just retrieved. + */ + bool GetToken(irc::string &token); + + /** Fetch the next token from the stream as an integer + * @param token The next token available, or undefined if none remain + * @return True if tokens are left to be read, false if the last token was just retrieved. + */ + bool GetToken(int &token); + + /** Fetch the next token from the stream as a long integer + * @param token The next token available, or undefined if none remain + * @return True if tokens are left to be read, false if the last token was just retrieved. + */ + bool GetToken(long &token); + }; + + /** irc::sepstream allows for splitting token seperated lists. + * Each successive call to sepstream::GetToken() returns + * the next token, until none remain, at which point the method returns + * an empty string. + */ + class CoreExport sepstream : public classbase + { + private: + /** Original string. + */ + std::string tokens; + /** Last position of a seperator token + */ + std::string::iterator last_starting_position; + /** Current string position + */ + std::string::iterator n; + /** Seperator value + */ + char sep; + public: + /** Create a sepstream and fill it with the provided data + */ + sepstream(const std::string &source, char seperator); + virtual ~sepstream(); + + /** Fetch the next token from the stream + * @return The next token is returned, or an empty string if none remain + */ + virtual const std::string GetToken(); + + /** Fetch the entire remaining stream, without tokenizing + * @return The remaining part of the stream + */ + virtual const std::string GetRemaining(); + + /** Returns true if the end of the stream has been reached + * @return True if the end of the stream has been reached, otherwise false + */ + virtual bool StreamEnd(); + }; + + /** A derived form of sepstream, which seperates on commas + */ + class CoreExport commasepstream : public sepstream + { + public: + /** Initialize with comma seperator + */ + commasepstream(const std::string &source) : sepstream(source, ',') + { + } + }; + + /** A derived form of sepstream, which seperates on spaces + */ + class CoreExport spacesepstream : public sepstream + { + public: + /** Initialize with space seperator + */ + spacesepstream(const std::string &source) : sepstream(source, ' ') + { + } + }; + + /** The portparser class seperates out a port range into integers. + * A port range may be specified in the input string in the form + * "6660,6661,6662-6669,7020". The end of the stream is indicated by + * a return value of 0 from portparser::GetToken(). If you attempt + * to specify an illegal range (e.g. one where start >= end, or + * start or end < 0) then GetToken() will return the first element + * of the pair of numbers. + */ + class CoreExport portparser : public classbase + { + private: + /** Used to split on commas + */ + commasepstream* sep; + /** Current position in a range of ports + */ + long in_range; + /** Starting port in a range of ports + */ + long range_begin; + /** Ending port in a range of ports + */ + long range_end; + /** Allow overlapped port ranges + */ + bool overlapped; + /** Used to determine overlapping of ports + * without O(n) algorithm being used + */ + std::map<long, bool> overlap_set; + /** Returns true if val overlaps an existing range + */ + bool Overlaps(long val); + public: + /** Create a portparser and fill it with the provided data + * @param source The source text to parse from + * @param allow_overlapped Allow overlapped ranges + */ + portparser(const std::string &source, bool allow_overlapped = true); + /** Frees the internal commasepstream object + */ + ~portparser(); + /** Fetch the next token from the stream + * @return The next port number is returned, or 0 if none remain + */ + long GetToken(); + }; + + /** Used to hold a bitfield definition in dynamicbitmask. + * You must be allocated one of these by dynamicbitmask::Allocate(), + * you should not fill the values yourself! + */ + typedef std::pair<size_t, unsigned char> bitfield; + + /** The irc::dynamicbitmask class is used to maintain a bitmap of + * boolean values, which can grow to any reasonable size no matter + * how many bitfields are in it. + * + * It starts off at 32 bits in size, large enough to hold 32 boolean + * values, with a memory allocation of 8 bytes. If you allocate more + * than 32 bits, the class will grow the bitmap by 8 bytes at a time + * for each set of 8 bitfields you allocate with the Allocate() + * method. + * + * This method is designed so that multiple modules can be allocated + * bit values in a bitmap dynamically, rather than having to define + * costs in a fixed size unsigned integer and having the possibility + * of collisions of values in different third party modules. + * + * IMPORTANT NOTE: + * + * To use this class, you must derive from it. + * This is because each derived instance has its own freebits array + * which can determine what bitfields are allocated on a TYPE BY TYPE + * basis, e.g. an irc::dynamicbitmask type for userrecs, and one for + * chanrecs, etc. You should inheret it in a very simple way as follows. + * The base class will resize and maintain freebits as required, you are + * just required to make the pointer static and specific to this class + * type. + * + * \code + * class mydbitmask : public irc::dynamicbitmask + * { + * private: + * + * static unsigned char* freebits; + * + * public: + * + * mydbitmask() : irc::dynamicbitmask() + * { + * freebits = new unsigned char[this->bits_size]; + * memset(freebits, 0, this->bits_size); + * } + * + * ~mydbitmask() + * { + * delete[] freebits; + * } + * + * unsigned char* GetFreeBits() + * { + * return freebits; + * } + * + * void SetFreeBits(unsigned char* freebt) + * { + * freebits = freebt; + * } + * }; + * \endcode + */ + class CoreExport dynamicbitmask : public classbase + { + private: + /** Data bits. We start with four of these, + * and we grow the bitfield as we allocate + * more than 32 entries with Allocate(). + */ + unsigned char* bits; + protected: + /** Current set size (size of freebits and bits). + * Both freebits and bits will ALWAYS be the + * same length. + */ + unsigned char bits_size; + public: + /** Allocate the initial memory for bits and + * freebits and zero the memory. + */ + dynamicbitmask(); + + /** Free the memory used by bits and freebits + */ + virtual ~dynamicbitmask(); + + /** Allocate an irc::bitfield. + * @return An irc::bitfield which can be used + * with Get, Deallocate and Toggle methods. + * @throw Can throw std::bad_alloc if there is + * no ram left to grow the bitmask. + */ + bitfield Allocate(); + + /** Deallocate an irc::bitfield. + * @param An irc::bitfield to deallocate. + * @return True if the bitfield could be + * deallocated, false if it could not. + */ + bool Deallocate(bitfield &pos); + + /** Toggle the value of a bitfield. + * @param pos A bitfield to allocate, previously + * allocated by dyamicbitmask::Allocate(). + * @param state The state to set the field to. + */ + void Toggle(bitfield &pos, bool state); + + /** Get the value of a bitfield. + * @param pos A bitfield to retrieve, previously + * allocated by dyamicbitmask::Allocate(). + * @return The value of the bitfield. + * @throw Will throw ModuleException if the bitfield + * you provide is outside of the range + * 0 >= bitfield.first < size_bits. + */ + bool Get(bitfield &pos); + + /** Return the size in bytes allocated to the bits + * array. + * Note that the actual allocation is twice this, + * as there are an equal number of bytes allocated + * for the freebits array. + */ + unsigned char GetSize(); + + /** Get free bits mask + */ + virtual unsigned char* GetFreeBits() { return NULL; } + + /** Set free bits mask + */ + virtual void SetFreeBits(unsigned char* freebits) { } + }; + + /** Turn _ characters in a string into spaces + * @param n String to translate + * @return The new value with _ translated to space. + */ + CoreExport const char* Spacify(const char* n); +} + +/* Define operators for using >> and << with irc::string to an ostream on an istream. */ +/* This was endless fun. No. Really. */ +/* It was also the first core change Ommeh made, if anyone cares */ + +/** Operator << for irc::string + */ +inline std::ostream& operator<<(std::ostream &os, const irc::string &str) { return os << str.c_str(); } + +/** Operator >> for irc::string + */ +inline std::istream& operator>>(std::istream &is, irc::string &str) +{ + std::string tmp; + is >> tmp; + str = tmp.c_str(); + return is; +} + +/* Define operators for + and == with irc::string to std::string for easy assignment + * and comparison + * + * Operator + + */ +inline std::string operator+ (std::string& leftval, irc::string& rightval) +{ + return leftval + std::string(rightval.c_str()); +} + +/* Define operators for + and == with irc::string to std::string for easy assignment + * and comparison + * + * Operator + + */ +inline irc::string operator+ (irc::string& leftval, std::string& rightval) +{ + return leftval + irc::string(rightval.c_str()); +} + +/* Define operators for + and == with irc::string to std::string for easy assignment + * and comparison + * + * Operator == + */ +inline bool operator== (const std::string& leftval, const irc::string& rightval) +{ + return (leftval.c_str() == rightval); +} + +/* Define operators for + and == with irc::string to std::string for easy assignment + * and comparison + * + * Operator == + */ +inline bool operator== (const irc::string& leftval, const std::string& rightval) +{ + return (leftval == rightval.c_str()); +} + +/** Assign an irc::string to a std::string. + */ +inline std::string assign(const irc::string &other) { return other.c_str(); } + +/** Assign a std::string to an irc::string. + */ +inline irc::string assign(const std::string &other) { return other.c_str(); } + +/** Trim the leading and trailing spaces from a std::string. + */ +inline std::string& trim(std::string &str) +{ + std::string::size_type start = str.find_first_not_of(" "); + std::string::size_type end = str.find_last_not_of(" "); + if (start == std::string::npos || end == std::string::npos) + str = ""; + else + str = str.substr(start, end-start+1); + + return str; +} + +/** Hashing stuff is totally different on vc++'s hash_map implementation, so to save a buttload of + * #ifdefs we'll just do it all at once + */ +namespace nspace +{ + /** Hashing function to hash irc::string + */ +#ifdef WINDOWS + template<> class CoreExport hash_compare<irc::string, std::less<irc::string> > + { + public: + enum { bucket_size = 4, min_buckets = 8 }; /* Got these numbers from the CRT source, if anyone wants to change them feel free. */ + + /** Compare two irc::string values for hashing in hash_map + */ + bool operator()(const irc::string & s1, const irc::string & s2) const + { + if(s1.length() != s2.length()) return true; + return (irc::irc_char_traits::compare(s1.c_str(), s2.c_str(), s1.length()) < 0); + } + + /** Hash an irc::string value for hash_map + */ + size_t operator()(const irc::string & s) const; + }; + + template<> class CoreExport hash_compare<std::string, std::less<std::string> > + { + public: + enum { bucket_size = 4, min_buckets = 8 }; /* Again, from the CRT source */ + + /** Compare two std::string values for hashing in hash_map + */ + bool operator()(const std::string & s1, const std::string & s2) const + { + if(s1.length() != s2.length()) return true; + return (irc::irc_char_traits::compare(s1.c_str(), s2.c_str(), s1.length()) < 0); + } + + /** Hash a std::string using RFC1459 case sensitivity rules + * @param s A string to hash + * @return The hash value + */ + size_t operator()(const std::string & s) const; + }; +#else + template<> struct hash<irc::string> + { + /** Hash an irc::string using RFC1459 case sensitivity rules + * @param s A string to hash + * @return The hash value + */ + size_t operator()(const irc::string &s) const; + }; + + template<> struct hash<std::string> + { + /** Hash a std::string using RFC1459 case sensitivity rules + * @param s A string to hash + * @return The hash value + */ + size_t operator()(const string &s) const; + }; +#endif + + /** Convert a string to lower case respecting RFC1459 + * @param n A string to lowercase + */ + void strlower(char *n); +} + +#endif + diff --git a/include/inspircd.h b/include/inspircd.h index 378ca4ec1..c3f8ed328 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -1 +1,1279 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __INSPIRCD_H__
#define __INSPIRCD_H__
#ifndef WIN32
#define DllExport
#define CoreExport
#define printf_c printf
#else
#include "inspircd_win32wrapper.h"
/** Windows defines these already */
#undef DELETE
#undef ERROR
#endif
#include <time.h>
#include <string>
#include <sstream>
#include "inspircd_config.h"
#include "users.h"
#include "channels.h"
#include "socket.h"
#include "mode.h"
#include "socketengine.h"
#include "command_parse.h"
#include "snomasks.h"
#include "cull_list.h"
/** Returned by some functions to indicate failure.
*/
#define ERROR -1
/** Support for librodent -
* see http://www.chatspike.net/index.php?z=64
*/
#define ETIREDHAMSTERS EAGAIN
/** Debug levels for use with InspIRCd::Log()
*/
enum DebugLevel
{
DEBUG = 10,
VERBOSE = 20,
DEFAULT = 30,
SPARSE = 40,
NONE = 50
};
/**
* This define is used in place of strcmp when we
* want to check if a char* string contains only one
* letter. Pretty fast, its just two compares and an
* addition.
*/
#define IS_SINGLE(x,y) ( (*x == y) && (*(x+1) == 0) )
/** Delete a pointer, and NULL its value
*/
template<typename T> inline void DELETE(T* x)
{
delete x;
x = NULL;
}
/** Template function to convert any input type to std::string
*/
template<typename T> inline std::string ConvNumeric(const T &in)
{
if (in == 0) return "0";
char res[MAXBUF];
char* out = res;
T quotient = in;
while (quotient) {
*out = "0123456789"[ std::abs( (long)quotient % 10 ) ];
++out;
quotient /= 10;
}
if ( in < 0)
*out++ = '-';
*out = 0;
std::reverse(res,out);
return res;
}
/** Template function to convert any input type to std::string
*/
inline std::string ConvToStr(const int in)
{
return ConvNumeric(in);
}
/** Template function to convert any input type to std::string
*/
inline std::string ConvToStr(const long in)
{
return ConvNumeric(in);
}
/** Template function to convert any input type to std::string
*/
inline std::string ConvToStr(const unsigned long in)
{
return ConvNumeric(in);
}
/** Template function to convert any input type to std::string
*/
inline std::string ConvToStr(const char* in)
{
return in;
}
/** Template function to convert any input type to std::string
*/
inline std::string ConvToStr(const bool in)
{
return (in ? "1" : "0");
}
/** Template function to convert any input type to std::string
*/
inline std::string ConvToStr(char in)
{
return std::string(in,1);
}
/** Template function to convert any input type to std::string
*/
template <class T> inline std::string ConvToStr(const T &in)
{
std::stringstream tmp;
if (!(tmp << in)) return std::string();
return tmp.str();
}
/** Template function to convert any input type to any other type
* (usually an integer or numeric type)
*/
template<typename T> inline long ConvToInt(const T &in)
{
std::stringstream tmp;
if (!(tmp << in)) return 0;
return atoi(tmp.str().c_str());
}
/** Template function to convert integer to char, storing result in *res and
* also returning the pointer to res. Based on Stuart Lowe's C/C++ Pages.
* @param T input value
* @param V result value
* @param R base to convert to
*/
template<typename T, typename V, typename R> inline char* itoa(const T &in, V *res, R base)
{
if (base < 2 || base > 16) { *res = 0; return res; }
char* out = res;
int quotient = in;
while (quotient) {
*out = "0123456789abcdef"[ std::abs( quotient % base ) ];
++out;
quotient /= base;
}
if ( in < 0 && base == 10) *out++ = '-';
std::reverse( res, out );
*out = 0;
return res;
}
/** This class contains various STATS counters
* It is used by the InspIRCd class, which internally
* has an instance of it.
*/
class serverstats : public classbase
{
public:
/** Number of accepted connections
*/
unsigned long statsAccept;
/** Number of failed accepts
*/
unsigned long statsRefused;
/** Number of unknown commands seen
*/
unsigned long statsUnknown;
/** Number of nickname collisions handled
*/
unsigned long statsCollisions;
/** Number of DNS queries sent out
*/
unsigned long statsDns;
/** Number of good DNS replies received
* NOTE: This may not tally to the number sent out,
* due to timeouts and other latency issues.
*/
unsigned long statsDnsGood;
/** Number of bad (negative) DNS replies received
* NOTE: This may not tally to the number sent out,
* due to timeouts and other latency issues.
*/
unsigned long statsDnsBad;
/** Number of inbound connections seen
*/
unsigned long statsConnects;
/** Total bytes of data transmitted
*/
double statsSent;
/** Total bytes of data received
*/
double statsRecv;
/** Cpu usage at last sample
*/
timeval LastCPU;
/** Time last sample was read
*/
timeval LastSampled;
/** The constructor initializes all the counts to zero
*/
serverstats()
: statsAccept(0), statsRefused(0), statsUnknown(0), statsCollisions(0), statsDns(0),
statsDnsGood(0), statsDnsBad(0), statsConnects(0), statsSent(0.0), statsRecv(0.0)
{
}
};
/* Forward declaration -- required */
class InspIRCd;
/** This class implements a nonblocking log-writer.
* Most people writing an ircd give little thought to their disk
* i/o. On a congested system, disk writes can block for long
* periods of time (e.g. if the system is busy and/or swapping
* a lot). If we just use a blocking fprintf() call, this could
* block for undesirable amounts of time (half of a second through
* to whole seconds). We DO NOT want this, so we make our logfile
* nonblocking and hook it into the SocketEngine.
* NB: If the operating system does not support nonblocking file
* I/O (linux seems to, as does freebsd) this will default to
* blocking behaviour.
*/
class CoreExport FileLogger : public EventHandler
{
protected:
/** The creator/owner of this object
*/
InspIRCd* ServerInstance;
/** The log file (fd is inside this somewhere,
* we get it out with fileno())
*/
FILE* log;
/** Buffer of pending log lines to be written
*/
std::string buffer;
/** Number of write operations that have occured
*/
int writeops;
public:
/** The constructor takes an already opened logfile.
*/
FileLogger(InspIRCd* Instance, FILE* logfile);
/** This returns false, logfiles are writeable.
*/
virtual bool Readable();
/** Handle pending write events.
* This will flush any waiting data to disk.
* If any data remains after the fprintf call,
* another write event is scheduled to write
* the rest of the data when possible.
*/
virtual void HandleEvent(EventType et, int errornum = 0);
/** Write one or more preformatted log lines.
* If the data cannot be written immediately,
* this class will insert itself into the
* SocketEngine, and register a write event,
* and when the write event occurs it will
* attempt again to write the data.
*/
void WriteLogLine(const std::string &line);
/** Close the log file and cancel any events.
*/
virtual void Close();
/** Close the log file and cancel any events.
* (indirectly call Close()
*/
virtual ~FileLogger();
};
/** A list of failed port bindings, used for informational purposes on startup */
typedef std::vector<std::pair<std::string, long> > FailedPortList;
/** A list of ip addresses cross referenced against clone counts */
typedef std::map<irc::string, unsigned int> clonemap;
/* Forward declaration - required */
class XLineManager;
/** The main class of the irc server.
* This class contains instances of all the other classes
* in this software, with the exception of the base class,
* classbase. Amongst other things, it contains a ModeParser,
* a DNS object, a CommandParser object, and a list of active
* Module objects, and facilities for Module objects to
* interact with the core system it implements. You should
* NEVER attempt to instantiate a class of type InspIRCd
* yourself. If you do, this is equivalent to spawning a second
* IRC server, and could have catastrophic consequences for the
* program in terms of ram usage (basically, you could create
* an obese forkbomb built from recursively spawning irc servers!)
*/
class CoreExport InspIRCd : public classbase
{
private:
/** Holds a string describing the last module error to occur
*/
char MODERR[MAXBUF];
/** Remove a ModuleFactory pointer
* @param j Index number of the ModuleFactory to remove
*/
void EraseFactory(int j);
/** Remove a Module pointer
* @param j Index number of the Module to remove
*/
void EraseModule(int j);
/** Move a given module to a specific slot in the list
* @param modulename The module name to relocate
* @param slot The slot to move the module into
*/
void MoveTo(std::string modulename,int slot);
/** Display the startup banner
*/
void Start();
/** Set up the signal handlers
*/
void SetSignals();
/** Daemonize the ircd and close standard input/output streams
* @return True if the program daemonized succesfully
*/
bool DaemonSeed();
/** Moves the given module to the last slot in the list
* @param modulename The module name to relocate
*/
void MoveToLast(std::string modulename);
/** Moves the given module to the first slot in the list
* @param modulename The module name to relocate
*/
void MoveToFirst(std::string modulename);
/** Moves one module to be placed after another in the list
* @param modulename The module name to relocate
* @param after The module name to place the module after
*/
void MoveAfter(std::string modulename, std::string after);
/** Moves one module to be placed before another in the list
* @param modulename The module name to relocate
* @param after The module name to place the module before
*/
void MoveBefore(std::string modulename, std::string before);
/** Iterate the list of InspSocket objects, removing ones which have timed out
* @param TIME the current time
*/
void DoSocketTimeouts(time_t TIME);
/** Perform background user events such as PING checks
* @param TIME the current time
*/
void DoBackgroundUserStuff(time_t TIME);
/** Returns true when all modules have done pre-registration checks on a user
* @param user The user to verify
* @return True if all modules have finished checking this user
*/
bool AllModulesReportReady(userrec* user);
/** Total number of modules loaded into the ircd, minus one
*/
int ModCount;
/** Logfile pathname specified on the commandline, or empty string
*/
char LogFileName[MAXBUF];
/** The feature names published by various modules
*/
featurelist Features;
/** The interface names published by various modules
*/
interfacelist Interfaces;
/** The current time, updated in the mainloop
*/
time_t TIME;
/** The time that was recorded last time around the mainloop
*/
time_t OLDTIME;
/** A 64k buffer used to read client lines into
*/
char ReadBuffer[65535];
/** Used when connecting clients
*/
insp_sockaddr client, server;
/** Used when connecting clients
*/
socklen_t length;
/** Nonblocking file writer
*/
FileLogger* Logger;
/** Time offset in seconds
* This offset is added to all calls to Time(). Use SetTimeDelta() to update
*/
int time_delta;
public:
/** InspSocket classes pending deletion after being closed.
* We don't delete these immediately as this may cause a segmentation fault.
*/
std::map<InspSocket*,InspSocket*> SocketCull;
/** Build the ISUPPORT string by triggering all modules On005Numeric events
*/
void BuildISupport();
/** Number of unregistered users online right now.
* (Unregistered means before USER/NICK/dns)
*/
int unregistered_count;
/** List of server names we've seen.
*/
servernamelist servernames;
/** Time this ircd was booted
*/
time_t startup_time;
/** Config file pathname specified on the commandline or via ./configure
*/
char ConfigFileName[MAXBUF];
/** Mode handler, handles mode setting and removal
*/
ModeParser* Modes;
/** Command parser, handles client to server commands
*/
CommandParser* Parser;
/** Socket engine, handles socket activity events
*/
SocketEngine* SE;
/** Stats class, holds miscellaneous stats counters
*/
serverstats* stats;
/** Server Config class, holds configuration file data
*/
ServerConfig* Config;
/** Snomask manager - handles routing of snomask messages
* to opers.
*/
SnomaskManager* SNO;
/** Client list, a hash_map containing all clients, local and remote
*/
user_hash* clientlist;
/** Channel list, a hash_map containing all channels
*/
chan_hash* chanlist;
/** Local client list, a vector containing only local clients
*/
std::vector<userrec*> local_users;
/** Oper list, a vector containing all local and remote opered users
*/
std::vector<userrec*> all_opers;
/** Map of local ip addresses for clone counting
*/
clonemap local_clones;
/** Map of global ip addresses for clone counting
*/
clonemap global_clones;
/** DNS class, provides resolver facilities to the core and modules
*/
DNS* Res;
/** Timer manager class, triggers InspTimer timer events
*/
TimerManager* Timers;
/** X-Line manager. Handles G/K/Q/E line setting, removal and matching
*/
XLineManager* XLines;
/** A list of Module* module classes
* Note that this list is always exactly 255 in size.
* The actual number of loaded modules is available from GetModuleCount()
*/
ModuleList modules;
/** A list of ModuleFactory* module factories
* Note that this list is always exactly 255 in size.
* The actual number of loaded modules is available from GetModuleCount()
*/
FactoryList factory;
/** The time we next call our ping timeout and reg timeout checks
*/
time_t next_call;
/** Global cull list, will be processed on next iteration
*/
CullList GlobalCulls;
/** Get the current time
* Because this only calls time() once every time around the mainloop,
* it is much faster than calling time() directly.
* @param delta True to use the delta as an offset, false otherwise
* @return The current time as an epoch value (time_t)
*/
time_t Time(bool delta = false);
/** Set the time offset in seconds
* This offset is added to Time() to offset the system time by the specified
* number of seconds.
* @param delta The number of seconds to offset
* @return The old time delta
*/
int SetTimeDelta(int delta);
/** Add a user to the local clone map
* @param user The user to add
*/
void AddLocalClone(userrec* user);
/** Add a user to the global clone map
* @param user The user to add
*/
void AddGlobalClone(userrec* user);
/** Number of users with a certain mode set on them
*/
int ModeCount(const char mode);
/** Get the time offset in seconds
* @return The current time delta (in seconds)
*/
int GetTimeDelta();
/** Process a user whos socket has been flagged as active
* @param cu The user to process
* @return There is no actual return value, however upon exit, the user 'cu' may have been
* marked for deletion in the global CullList.
*/
void ProcessUser(userrec* cu);
/** Get the total number of currently loaded modules
* @return The number of loaded modules
*/
int GetModuleCount();
/** Find a module by name, and return a Module* to it.
* This is preferred over iterating the module lists yourself.
* @param name The module name to look up
* @return A pointer to the module, or NULL if the module cannot be found
*/
Module* FindModule(const std::string &name);
/** Bind all ports specified in the configuration file.
* @param bail True if the function should bail back to the shell on failure
* @param found_ports The actual number of ports found in the config, as opposed to the number actually bound
* @return The number of ports actually bound without error
*/
int BindPorts(bool bail, int &found_ports, FailedPortList &failed_ports);
/** Binds a socket on an already open file descriptor
* @param sockfd A valid file descriptor of an open socket
* @param port The port number to bind to
* @param addr The address to bind to (IP only)
* @return True if the port was bound successfully
*/
bool BindSocket(int sockfd, int port, char* addr, bool dolisten = true);
/** Adds a server name to the list of servers we've seen
* @param The servername to add
*/
void AddServerName(const std::string &servername);
/** Finds a cached char* pointer of a server name,
* This is used to optimize userrec by storing only the pointer to the name
* @param The servername to find
* @return A pointer to this name, gauranteed to never become invalid
*/
const char* FindServerNamePtr(const std::string &servername);
/** Returns true if we've seen the given server name before
* @param The servername to find
* @return True if we've seen this server name before
*/
bool FindServerName(const std::string &servername);
/** Gets the GECOS (description) field of the given server.
* If the servername is not that of the local server, the name
* is passed to handling modules which will attempt to determine
* the GECOS that bleongs to the given servername.
* @param servername The servername to find the description of
* @return The description of this server, or of the local server
*/
std::string GetServerDescription(const char* servername);
/** Write text to all opers connected to this server
* @param text The text format string
* @param ... Format args
*/
void WriteOpers(const char* text, ...);
/** Write text to all opers connected to this server
* @param text The text to send
*/
void WriteOpers(const std::string &text);
/** Find a nickname in the nick hash
* @param nick The nickname to find
* @return A pointer to the user, or NULL if the user does not exist
*/
userrec* FindNick(const std::string &nick);
/** Find a nickname in the nick hash
* @param nick The nickname to find
* @return A pointer to the user, or NULL if the user does not exist
*/
userrec* FindNick(const char* nick);
/** Find a channel in the channels hash
* @param chan The channel to find
* @return A pointer to the channel, or NULL if the channel does not exist
*/
chanrec* FindChan(const std::string &chan);
/** Find a channel in the channels hash
* @param chan The channel to find
* @return A pointer to the channel, or NULL if the channel does not exist
*/
chanrec* FindChan(const char* chan);
/** Called by the constructor to load all modules from the config file.
*/
void LoadAllModules();
/** Check for a 'die' tag in the config file, and abort if found
* @return Depending on the configuration, this function may never return
*/
void CheckDie();
/** Check we aren't running as root, and exit if we are
* @return Depending on the configuration, this function may never return
*/
void CheckRoot();
/** Determine the right path for, and open, the logfile
* @param argv The argv passed to main() initially, used to calculate program path
* @param argc The argc passed to main() initially, used to calculate program path
*/
void OpenLog(char** argv, int argc);
/** Close the currently open log file
*/
void CloseLog();
/** Send a server notice to all local users
* @param text The text format string to send
* @param ... The format arguments
*/
void ServerNoticeAll(char* text, ...);
/** Send a server message (PRIVMSG) to all local users
* @param text The text format string to send
* @param ... The format arguments
*/
void ServerPrivmsgAll(char* text, ...);
/** Send text to all users with a specific set of modes
* @param modes The modes to check against, without a +, e.g. 'og'
* @param flags one of WM_OR or WM_AND. If you specify WM_OR, any one of the
* mode characters in the first parameter causes receipt of the message, and
* if you specify WM_OR, all the modes must be present.
* @param text The text format string to send
* @param ... The format arguments
*/
void WriteMode(const char* modes, int flags, const char* text, ...);
/** Return true if a channel name is valid
* @param chname A channel name to verify
* @return True if the name is valid
*/
bool IsChannel(const char *chname);
/** Rehash the local server
* @param status This value is unused, and required for signal handler functions
*/
static void Rehash(int status);
/** Causes the server to exit after unloading modules and
* closing all open file descriptors.
*
* @param The exit code to give to the operating system
* (See the ExitStatus enum for valid values)
*/
static void Exit(int status);
/** Causes the server to exit immediately with exit code 0.
* The status code is required for signal handlers, and ignored.
*/
static void QuickExit(int status);
/** Return a count of users, unknown and known connections
* @return The number of users
*/
int UserCount();
/** Return a count of fully registered connections only
* @return The number of registered users
*/
int RegisteredUserCount();
/** Return a count of invisible (umode +i) users only
* @return The number of invisible users
*/
int InvisibleUserCount();
/** Return a count of opered (umode +o) users only
* @return The number of opers
*/
int OperCount();
/** Return a count of unregistered (before NICK/USER) users only
* @return The number of unregistered (unknown) connections
*/
int UnregisteredUserCount();
/** Return a count of channels on the network
* @return The number of channels
*/
long ChannelCount();
/** Return a count of local users on this server only
* @return The number of local users
*/
long LocalUserCount();
/** Send an error notice to all local users, opered and unopered
* @param s The error string to send
*/
void SendError(const std::string &s);
/** For use with Module::Prioritize().
* When the return value of this function is returned from
* Module::Prioritize(), this specifies that the module wishes
* to be ordered exactly BEFORE 'modulename'. For more information
* please see Module::Prioritize().
* @param modulename The module your module wants to be before in the call list
* @returns a priority ID which the core uses to relocate the module in the list
*/
long PriorityBefore(const std::string &modulename);
/** For use with Module::Prioritize().
* When the return value of this function is returned from
* Module::Prioritize(), this specifies that the module wishes
* to be ordered exactly AFTER 'modulename'. For more information please
* see Module::Prioritize().
* @param modulename The module your module wants to be after in the call list
* @returns a priority ID which the core uses to relocate the module in the list
*/
long PriorityAfter(const std::string &modulename);
/** Publish a 'feature'.
* There are two ways for a module to find another module it depends on.
* Either by name, using InspIRCd::FindModule, or by feature, using this
* function. A feature is an arbitary string which identifies something this
* module can do. For example, if your module provides SSL support, but other
* modules provide SSL support too, all the modules supporting SSL should
* publish an identical 'SSL' feature. This way, any module requiring use
* of SSL functions can just look up the 'SSL' feature using FindFeature,
* then use the module pointer they are given.
* @param FeatureName The case sensitive feature name to make available
* @param Mod a pointer to your module class
* @returns True on success, false if the feature is already published by
* another module.
*/
bool PublishFeature(const std::string &FeatureName, Module* Mod);
/** Publish a module to an 'interface'.
* Modules which implement the same interface (the same way of communicating
* with other modules) can publish themselves to an interface, using this
* method. When they do so, they become part of a list of related or
* compatible modules, and a third module may then query for that list
* and know that all modules within that list offer the same API.
* A prime example of this is the hashing modules, which all accept the
* same types of Request class. Consider this to be similar to PublishFeature,
* except for that multiple modules may publish the same 'feature'.
* @param InterfaceName The case sensitive interface name to make available
* @param Mod a pointer to your module class
* @returns True on success, false on failure (there are currently no failure
* cases)
*/
bool PublishInterface(const std::string &InterfaceName, Module* Mod);
/** Return a pair saying how many other modules are currently using the
* interfaces provided by module m.
* @param m The module to count usage for
* @return A pair, where the first value is the number of uses of the interface,
* and the second value is the interface name being used.
*/
std::pair<int,std::string> GetInterfaceInstanceCount(Module* m);
/** Mark your module as using an interface.
* If you mark your module as using an interface, then that interface
* module may not unload until your module has unloaded first.
* This can be used to prevent crashes by ensuring code you depend on
* is always in memory while your module is active.
* @param InterfaceName The interface to use
*/
void UseInterface(const std::string &InterfaceName);
/** Mark your module as finished with an interface.
* If you used UseInterface() above, you should use this method when
* your module is finished with the interface (usually in its destructor)
* to allow the modules which implement the given interface to be unloaded.
* @param InterfaceName The interface you are finished with using.
*/
void DoneWithInterface(const std::string &InterfaceName);
/** Unpublish a 'feature'.
* When your module exits, it must call this method for every feature it
* is providing so that the feature table is cleaned up.
* @param FeatureName the feature to remove
*/
bool UnpublishFeature(const std::string &FeatureName);
/** Unpublish your module from an interface
* When your module exits, it must call this method for every interface
* it is part of so that the interfaces table is cleaned up. Only when
* the last item is deleted from an interface does the interface get
* removed.
* @param InterfaceName the interface to be removed from
* @param Mod The module to remove from the interface list
*/
bool UnpublishInterface(const std::string &InterfaceName, Module* Mod);
/** Find a 'feature'.
* There are two ways for a module to find another module it depends on.
* Either by name, using InspIRCd::FindModule, or by feature, using the
* InspIRCd::PublishFeature method. A feature is an arbitary string which
* identifies something this module can do. For example, if your module
* provides SSL support, but other modules provide SSL support too, all
* the modules supporting SSL should publish an identical 'SSL' feature.
* To find a module capable of providing the feature you want, simply
* call this method with the feature name you are looking for.
* @param FeatureName The feature name you wish to obtain the module for
* @returns A pointer to a valid module class on success, NULL on failure.
*/
Module* FindFeature(const std::string &FeatureName);
/** Find an 'interface'.
* An interface is a list of modules which all implement the same API.
* @param InterfaceName The Interface you wish to obtain the module
* list of.
* @return A pointer to a deque of Module*, or NULL if the interface
* does not exist.
*/
modulelist* FindInterface(const std::string &InterfaceName);
/** Given a pointer to a Module, return its filename
* @param m The module pointer to identify
* @return The module name or an empty string
*/
const std::string& GetModuleName(Module* m);
/** Return true if a nickname is valid
* @param n A nickname to verify
* @return True if the nick is valid
*/
bool IsNick(const char* n);
/** Return true if an ident is valid
* @param An ident to verify
* @return True if the ident is valid
*/
bool IsIdent(const char* n);
/** Find a username by their file descriptor.
* It is preferred to use this over directly accessing the fd_ref_table array.
* @param socket The file descriptor of a user
* @return A pointer to the user if the user exists locally on this descriptor
*/
userrec* FindDescriptor(int socket);
/** Add a new mode to this server's mode parser
* @param mh The modehandler to add
* @param modechar The mode character this modehandler handles
* @return True if the mode handler was added
*/
bool AddMode(ModeHandler* mh, const unsigned char modechar);
/** Add a new mode watcher to this server's mode parser
* @param mw The modewatcher to add
* @return True if the modewatcher was added
*/
bool AddModeWatcher(ModeWatcher* mw);
/** Delete a mode watcher from this server's mode parser
* @param mw The modewatcher to delete
* @return True if the modewatcher was deleted
*/
bool DelModeWatcher(ModeWatcher* mw);
/** Add a dns Resolver class to this server's active set
* @param r The resolver to add
* @param cached If this value is true, then the cache will
* be searched for the DNS result, immediately. If the value is
* false, then a request will be sent to the nameserver, and the
* result will not be immediately available. You should usually
* use the boolean value which you passed to the Resolver
* constructor, which Resolver will set appropriately depending
* on if cached results are available and haven't expired. It is
* however safe to force this value to false, forcing a remote DNS
* lookup, but not an update of the cache.
* @return True if the operation completed successfully. Note that
* if this method returns true, you should not attempt to access
* the resolver class you pass it after this call, as depending upon
* the request given, the object may be deleted!
*/
bool AddResolver(Resolver* r, bool cached);
/** Add a command to this server's command parser
* @param f A command_t command handler object to add
* @throw ModuleException Will throw ModuleExcption if the command already exists
*/
void AddCommand(command_t *f);
/** Send a modechange.
* The parameters provided are identical to that sent to the
* handler for class cmd_mode.
* @param parameters The mode parameters
* @param pcnt The number of items you have given in the first parameter
* @param user The user to send error messages to
*/
void SendMode(const char **parameters, int pcnt, userrec *user);
/** Match two strings using pattern matching.
* This operates identically to the global function match(),
* except for that it takes std::string arguments rather than
* const char* ones.
* @param sliteral The literal string to match against
* @param spattern The pattern to match against. CIDR and globs are supported.
*/
bool MatchText(const std::string &sliteral, const std::string &spattern);
/** Call the handler for a given command.
* @param commandname The command whos handler you wish to call
* @param parameters The mode parameters
* @param pcnt The number of items you have given in the first parameter
* @param user The user to execute the command as
* @return True if the command handler was called successfully
*/
CmdResult CallCommandHandler(const std::string &commandname, const char** parameters, int pcnt, userrec* user);
/** Return true if the command is a module-implemented command and the given parameters are valid for it
* @param parameters The mode parameters
* @param pcnt The number of items you have given in the first parameter
* @param user The user to test-execute the command as
* @return True if the command handler is a module command, and there are enough parameters and the user has permission to the command
*/
bool IsValidModuleCommand(const std::string &commandname, int pcnt, userrec* user);
/** Add a gline and apply it
* @param duration How long the line should last
* @param source Who set the line
* @param reason The reason for the line
* @param hostmask The hostmask to set the line against
*/
void AddGLine(long duration, const std::string &source, const std::string &reason, const std::string &hostmask);
/** Add a qline and apply it
* @param duration How long the line should last
* @param source Who set the line
* @param reason The reason for the line
* @param nickname The nickmask to set the line against
*/
void AddQLine(long duration, const std::string &source, const std::string &reason, const std::string &nickname);
/** Add a zline and apply it
* @param duration How long the line should last
* @param source Who set the line
* @param reason The reason for the line
* @param ipaddr The ip-mask to set the line against
*/
void AddZLine(long duration, const std::string &source, const std::string &reason, const std::string &ipaddr);
/** Add a kline and apply it
* @param duration How long the line should last
* @param source Who set the line
* @param reason The reason for the line
* @param hostmask The hostmask to set the line against
*/
void AddKLine(long duration, const std::string &source, const std::string &reason, const std::string &hostmask);
/** Add an eline
* @param duration How long the line should last
* @param source Who set the line
* @param reason The reason for the line
* @param hostmask The hostmask to set the line against
*/
void AddELine(long duration, const std::string &source, const std::string &reason, const std::string &hostmask);
/** Delete a gline
* @param hostmask The gline to delete
* @return True if the item was removed
*/
bool DelGLine(const std::string &hostmask);
/** Delete a qline
* @param nickname The qline to delete
* @return True if the item was removed
*/
bool DelQLine(const std::string &nickname);
/** Delete a zline
* @param ipaddr The zline to delete
* @return True if the item was removed
*/
bool DelZLine(const std::string &ipaddr);
/** Delete a kline
* @param hostmask The kline to delete
* @return True if the item was removed
*/
bool DelKLine(const std::string &hostmask);
/** Delete an eline
* @param hostmask The kline to delete
* @return True if the item was removed
*/
bool DelELine(const std::string &hostmask);
/** Return true if the given parameter is a valid nick!user\@host mask
* @param mask A nick!user\@host masak to match against
* @return True i the mask is valid
*/
bool IsValidMask(const std::string &mask);
/** Rehash the local server
*/
void RehashServer();
/** Return the channel whos index number matches that provided
* @param The index number of the channel to fetch
* @return A channel record, or NUll if index < 0 or index >= InspIRCd::ChannelCount()
*/
chanrec* GetChannelIndex(long index);
/** Dump text to a user target, splitting it appropriately to fit
* @param User the user to dump the text to
* @param LinePrefix text to prefix each complete line with
* @param TextStream the text to send to the user
*/
void DumpText(userrec* User, const std::string &LinePrefix, stringstream &TextStream);
/** Check if the given nickmask matches too many users, send errors to the given user
* @param nick A nickmask to match against
* @param user A user to send error text to
* @return True if the nick matches too many users
*/
bool NickMatchesEveryone(const std::string &nick, userrec* user);
/** Check if the given IP mask matches too many users, send errors to the given user
* @param ip An ipmask to match against
* @param user A user to send error text to
* @return True if the ip matches too many users
*/
bool IPMatchesEveryone(const std::string &ip, userrec* user);
/** Check if the given hostmask matches too many users, send errors to the given user
* @param mask A hostmask to match against
* @param user A user to send error text to
* @return True if the host matches too many users
*/
bool HostMatchesEveryone(const std::string &mask, userrec* user);
/** Calculate a duration in seconds from a string in the form 1y2w3d4h6m5s
* @param str A string containing a time in the form 1y2w3d4h6m5s
* (one year, two weeks, three days, four hours, six minutes and five seconds)
* @return The total number of seconds
*/
long Duration(const std::string &str);
/** Attempt to compare an oper password to a string from the config file.
* This will be passed to handling modules which will compare the data
* against possible hashed equivalents in the input string.
* @param data The data from the config file
* @param input The data input by the oper
* @param tagnum the tag number of the oper's tag in the config file
* @return 0 if the strings match, 1 or -1 if they do not
*/
int OperPassCompare(const char* data,const char* input, int tagnum);
/** Check if a given server is a uline.
* An empty string returns true, this is by design.
* @param server The server to check for uline status
* @return True if the server is a uline OR the string is empty
*/
bool ULine(const char* server);
/** Returns true if the uline is 'silent' (doesnt generate
* remote connect notices etc).
*/
bool SilentULine(const char* server);
/** Returns the subversion revision ID of this ircd
* @return The revision ID or an empty string
*/
std::string GetRevision();
/** Returns the full version string of this ircd
* @return The version string
*/
std::string GetVersionString();
/** Attempt to write the process id to a given file
* @param filename The PID file to attempt to write to
* @return This function may bail if the file cannot be written
*/
void WritePID(const std::string &filename);
/** Returns text describing the last module error
* @return The last error message to occur
*/
char* ModuleError();
/** Load a given module file
* @param filename The file to load
* @return True if the module was found and loaded
*/
bool LoadModule(const char* filename);
/** Unload a given module file
* @param filename The file to unload
* @return True if the module was unloaded
*/
bool UnloadModule(const char* filename);
/** This constructor initialises all the subsystems and reads the config file.
* @param argc The argument count passed to main()
* @param argv The argument list passed to main()
* @throw <anything> If anything is thrown from here and makes it to
* you, you should probably just give up and go home. Yes, really.
* It's that bad. Higher level classes should catch any non-fatal exceptions.
*/
InspIRCd(int argc, char** argv);
/** Do one iteration of the mainloop
* @param process_module_sockets True if module sockets are to be processed
* this time around the event loop. The is the default.
*/
void DoOneIteration(bool process_module_sockets = true);
/** Output a log message to the ircd.log file
* The text will only be output if the current loglevel
* is less than or equal to the level you provide
* @param level A log level from the DebugLevel enum
* @param text Format string of to write to the log
* @param ... Format arguments of text to write to the log
*/
void Log(int level, const char* text, ...);
/** Output a log message to the ircd.log file
* The text will only be output if the current loglevel
* is less than or equal to the level you provide
* @param level A log level from the DebugLevel enum
* @param text Text to write to the log
*/
void Log(int level, const std::string &text);
/** Send a line of WHOIS data to a user.
* @param user user to send the line to
* @param dest user being WHOISed
* @param numeric Numeric to send
* @param text Text of the numeric
*/
void SendWhoisLine(userrec* user, userrec* dest, int numeric, const std::string &text);
/** Send a line of WHOIS data to a user.
* @param user user to send the line to
* @param dest user being WHOISed
* @param numeric Numeric to send
* @param format Format string for the numeric
* @param ... Parameters for the format string
*/
void SendWhoisLine(userrec* user, userrec* dest, int numeric, const char* format, ...);
/** Quit a user for excess flood, and if they are not
* fully registered yet, temporarily zline their IP.
* @param current user to quit
*/
void FloodQuitUser(userrec* current);
/** Restart the server.
* This function will not return. If an error occurs,
* it will throw an instance of CoreException.
* @param reason The restart reason to show to all clients
* @throw CoreException An instance of CoreException indicating the error from execv().
*/
void Restart(const std::string &reason);
/** Prepare the ircd for restart or shutdown.
* This function unloads all modules which can be unloaded,
* closes all open sockets, and closes the logfile.
*/
void Cleanup();
/** This copies the user and channel hash_maps into new hash maps.
* This frees memory used by the hash_map allocator (which it neglects
* to free, most of the time, using tons of ram)
*/
void RehashUsersAndChans();
/** Resets the cached max bans value on all channels.
* Called by rehash.
*/
void ResetMaxBans();
/** Return a time_t as a human-readable string.
*/
std::string TimeString(time_t curtime);
/** Begin execution of the server.
* NOTE: this function NEVER returns. Internally,
* after performing some initialisation routines,
* it will repeatedly call DoOneIteration in a loop.
* @return The return value for this function is undefined.
*/
int Run();
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __INSPIRCD_H__ +#define __INSPIRCD_H__ + +#ifndef WIN32 +#define DllExport +#define CoreExport +#define printf_c printf +#else +#include "inspircd_win32wrapper.h" +/** Windows defines these already */ +#undef DELETE +#undef ERROR +#endif + +#include <time.h> +#include <string> +#include <sstream> +#include "inspircd_config.h" +#include "users.h" +#include "channels.h" +#include "socket.h" +#include "mode.h" +#include "socketengine.h" +#include "command_parse.h" +#include "snomasks.h" +#include "cull_list.h" + +/** Returned by some functions to indicate failure. + */ +#define ERROR -1 + +/** Support for librodent - + * see http://www.chatspike.net/index.php?z=64 + */ +#define ETIREDHAMSTERS EAGAIN + +/** Debug levels for use with InspIRCd::Log() + */ +enum DebugLevel +{ + DEBUG = 10, + VERBOSE = 20, + DEFAULT = 30, + SPARSE = 40, + NONE = 50 +}; + +/** + * This define is used in place of strcmp when we + * want to check if a char* string contains only one + * letter. Pretty fast, its just two compares and an + * addition. + */ +#define IS_SINGLE(x,y) ( (*x == y) && (*(x+1) == 0) ) + +/** Delete a pointer, and NULL its value + */ +template<typename T> inline void DELETE(T* x) +{ + delete x; + x = NULL; +} + +/** Template function to convert any input type to std::string + */ +template<typename T> inline std::string ConvNumeric(const T &in) +{ + if (in == 0) return "0"; + char res[MAXBUF]; + char* out = res; + T quotient = in; + while (quotient) { + *out = "0123456789"[ std::abs( (long)quotient % 10 ) ]; + ++out; + quotient /= 10; + } + if ( in < 0) + *out++ = '-'; + *out = 0; + std::reverse(res,out); + return res; +} + +/** Template function to convert any input type to std::string + */ +inline std::string ConvToStr(const int in) +{ + return ConvNumeric(in); +} + +/** Template function to convert any input type to std::string + */ +inline std::string ConvToStr(const long in) +{ + return ConvNumeric(in); +} + +/** Template function to convert any input type to std::string + */ +inline std::string ConvToStr(const unsigned long in) +{ + return ConvNumeric(in); +} + +/** Template function to convert any input type to std::string + */ +inline std::string ConvToStr(const char* in) +{ + return in; +} + +/** Template function to convert any input type to std::string + */ +inline std::string ConvToStr(const bool in) +{ + return (in ? "1" : "0"); +} + +/** Template function to convert any input type to std::string + */ +inline std::string ConvToStr(char in) +{ + return std::string(in,1); +} + +/** Template function to convert any input type to std::string + */ +template <class T> inline std::string ConvToStr(const T &in) +{ + std::stringstream tmp; + if (!(tmp << in)) return std::string(); + return tmp.str(); +} + +/** Template function to convert any input type to any other type + * (usually an integer or numeric type) + */ +template<typename T> inline long ConvToInt(const T &in) +{ + std::stringstream tmp; + if (!(tmp << in)) return 0; + return atoi(tmp.str().c_str()); +} + +/** Template function to convert integer to char, storing result in *res and + * also returning the pointer to res. Based on Stuart Lowe's C/C++ Pages. + * @param T input value + * @param V result value + * @param R base to convert to + */ +template<typename T, typename V, typename R> inline char* itoa(const T &in, V *res, R base) +{ + if (base < 2 || base > 16) { *res = 0; return res; } + char* out = res; + int quotient = in; + while (quotient) { + *out = "0123456789abcdef"[ std::abs( quotient % base ) ]; + ++out; + quotient /= base; + } + if ( in < 0 && base == 10) *out++ = '-'; + std::reverse( res, out ); + *out = 0; + return res; +} + +/** This class contains various STATS counters + * It is used by the InspIRCd class, which internally + * has an instance of it. + */ +class serverstats : public classbase +{ + public: + /** Number of accepted connections + */ + unsigned long statsAccept; + /** Number of failed accepts + */ + unsigned long statsRefused; + /** Number of unknown commands seen + */ + unsigned long statsUnknown; + /** Number of nickname collisions handled + */ + unsigned long statsCollisions; + /** Number of DNS queries sent out + */ + unsigned long statsDns; + /** Number of good DNS replies received + * NOTE: This may not tally to the number sent out, + * due to timeouts and other latency issues. + */ + unsigned long statsDnsGood; + /** Number of bad (negative) DNS replies received + * NOTE: This may not tally to the number sent out, + * due to timeouts and other latency issues. + */ + unsigned long statsDnsBad; + /** Number of inbound connections seen + */ + unsigned long statsConnects; + /** Total bytes of data transmitted + */ + double statsSent; + /** Total bytes of data received + */ + double statsRecv; + /** Cpu usage at last sample + */ + timeval LastCPU; + /** Time last sample was read + */ + timeval LastSampled; + /** The constructor initializes all the counts to zero + */ + serverstats() + : statsAccept(0), statsRefused(0), statsUnknown(0), statsCollisions(0), statsDns(0), + statsDnsGood(0), statsDnsBad(0), statsConnects(0), statsSent(0.0), statsRecv(0.0) + { + } +}; + +/* Forward declaration -- required */ +class InspIRCd; + +/** This class implements a nonblocking log-writer. + * Most people writing an ircd give little thought to their disk + * i/o. On a congested system, disk writes can block for long + * periods of time (e.g. if the system is busy and/or swapping + * a lot). If we just use a blocking fprintf() call, this could + * block for undesirable amounts of time (half of a second through + * to whole seconds). We DO NOT want this, so we make our logfile + * nonblocking and hook it into the SocketEngine. + * NB: If the operating system does not support nonblocking file + * I/O (linux seems to, as does freebsd) this will default to + * blocking behaviour. + */ +class CoreExport FileLogger : public EventHandler +{ + protected: + /** The creator/owner of this object + */ + InspIRCd* ServerInstance; + /** The log file (fd is inside this somewhere, + * we get it out with fileno()) + */ + FILE* log; + /** Buffer of pending log lines to be written + */ + std::string buffer; + /** Number of write operations that have occured + */ + int writeops; + public: + /** The constructor takes an already opened logfile. + */ + FileLogger(InspIRCd* Instance, FILE* logfile); + /** This returns false, logfiles are writeable. + */ + virtual bool Readable(); + /** Handle pending write events. + * This will flush any waiting data to disk. + * If any data remains after the fprintf call, + * another write event is scheduled to write + * the rest of the data when possible. + */ + virtual void HandleEvent(EventType et, int errornum = 0); + /** Write one or more preformatted log lines. + * If the data cannot be written immediately, + * this class will insert itself into the + * SocketEngine, and register a write event, + * and when the write event occurs it will + * attempt again to write the data. + */ + void WriteLogLine(const std::string &line); + /** Close the log file and cancel any events. + */ + virtual void Close(); + /** Close the log file and cancel any events. + * (indirectly call Close() + */ + virtual ~FileLogger(); +}; + +/** A list of failed port bindings, used for informational purposes on startup */ +typedef std::vector<std::pair<std::string, long> > FailedPortList; + +/** A list of ip addresses cross referenced against clone counts */ +typedef std::map<irc::string, unsigned int> clonemap; + +/* Forward declaration - required */ +class XLineManager; + +/** The main class of the irc server. + * This class contains instances of all the other classes + * in this software, with the exception of the base class, + * classbase. Amongst other things, it contains a ModeParser, + * a DNS object, a CommandParser object, and a list of active + * Module objects, and facilities for Module objects to + * interact with the core system it implements. You should + * NEVER attempt to instantiate a class of type InspIRCd + * yourself. If you do, this is equivalent to spawning a second + * IRC server, and could have catastrophic consequences for the + * program in terms of ram usage (basically, you could create + * an obese forkbomb built from recursively spawning irc servers!) + */ +class CoreExport InspIRCd : public classbase +{ + private: + /** Holds a string describing the last module error to occur + */ + char MODERR[MAXBUF]; + + /** Remove a ModuleFactory pointer + * @param j Index number of the ModuleFactory to remove + */ + void EraseFactory(int j); + + /** Remove a Module pointer + * @param j Index number of the Module to remove + */ + void EraseModule(int j); + + /** Move a given module to a specific slot in the list + * @param modulename The module name to relocate + * @param slot The slot to move the module into + */ + void MoveTo(std::string modulename,int slot); + + /** Display the startup banner + */ + void Start(); + + /** Set up the signal handlers + */ + void SetSignals(); + + /** Daemonize the ircd and close standard input/output streams + * @return True if the program daemonized succesfully + */ + bool DaemonSeed(); + + /** Moves the given module to the last slot in the list + * @param modulename The module name to relocate + */ + void MoveToLast(std::string modulename); + + /** Moves the given module to the first slot in the list + * @param modulename The module name to relocate + */ + void MoveToFirst(std::string modulename); + + /** Moves one module to be placed after another in the list + * @param modulename The module name to relocate + * @param after The module name to place the module after + */ + void MoveAfter(std::string modulename, std::string after); + + /** Moves one module to be placed before another in the list + * @param modulename The module name to relocate + * @param after The module name to place the module before + */ + void MoveBefore(std::string modulename, std::string before); + + /** Iterate the list of InspSocket objects, removing ones which have timed out + * @param TIME the current time + */ + void DoSocketTimeouts(time_t TIME); + + /** Perform background user events such as PING checks + * @param TIME the current time + */ + void DoBackgroundUserStuff(time_t TIME); + + /** Returns true when all modules have done pre-registration checks on a user + * @param user The user to verify + * @return True if all modules have finished checking this user + */ + bool AllModulesReportReady(userrec* user); + + /** Total number of modules loaded into the ircd, minus one + */ + int ModCount; + + /** Logfile pathname specified on the commandline, or empty string + */ + char LogFileName[MAXBUF]; + + /** The feature names published by various modules + */ + featurelist Features; + + /** The interface names published by various modules + */ + interfacelist Interfaces; + + /** The current time, updated in the mainloop + */ + time_t TIME; + + /** The time that was recorded last time around the mainloop + */ + time_t OLDTIME; + + /** A 64k buffer used to read client lines into + */ + char ReadBuffer[65535]; + + /** Used when connecting clients + */ + insp_sockaddr client, server; + + /** Used when connecting clients + */ + socklen_t length; + + /** Nonblocking file writer + */ + FileLogger* Logger; + + /** Time offset in seconds + * This offset is added to all calls to Time(). Use SetTimeDelta() to update + */ + int time_delta; + + public: + + /** InspSocket classes pending deletion after being closed. + * We don't delete these immediately as this may cause a segmentation fault. + */ + std::map<InspSocket*,InspSocket*> SocketCull; + + /** Build the ISUPPORT string by triggering all modules On005Numeric events + */ + void BuildISupport(); + + /** Number of unregistered users online right now. + * (Unregistered means before USER/NICK/dns) + */ + int unregistered_count; + + /** List of server names we've seen. + */ + servernamelist servernames; + + /** Time this ircd was booted + */ + time_t startup_time; + + /** Config file pathname specified on the commandline or via ./configure + */ + char ConfigFileName[MAXBUF]; + + /** Mode handler, handles mode setting and removal + */ + ModeParser* Modes; + + /** Command parser, handles client to server commands + */ + CommandParser* Parser; + + /** Socket engine, handles socket activity events + */ + SocketEngine* SE; + + /** Stats class, holds miscellaneous stats counters + */ + serverstats* stats; + + /** Server Config class, holds configuration file data + */ + ServerConfig* Config; + + /** Snomask manager - handles routing of snomask messages + * to opers. + */ + SnomaskManager* SNO; + + /** Client list, a hash_map containing all clients, local and remote + */ + user_hash* clientlist; + + /** Channel list, a hash_map containing all channels + */ + chan_hash* chanlist; + + /** Local client list, a vector containing only local clients + */ + std::vector<userrec*> local_users; + + /** Oper list, a vector containing all local and remote opered users + */ + std::vector<userrec*> all_opers; + + /** Map of local ip addresses for clone counting + */ + clonemap local_clones; + + /** Map of global ip addresses for clone counting + */ + clonemap global_clones; + + /** DNS class, provides resolver facilities to the core and modules + */ + DNS* Res; + + /** Timer manager class, triggers InspTimer timer events + */ + TimerManager* Timers; + + /** X-Line manager. Handles G/K/Q/E line setting, removal and matching + */ + XLineManager* XLines; + + /** A list of Module* module classes + * Note that this list is always exactly 255 in size. + * The actual number of loaded modules is available from GetModuleCount() + */ + ModuleList modules; + + /** A list of ModuleFactory* module factories + * Note that this list is always exactly 255 in size. + * The actual number of loaded modules is available from GetModuleCount() + */ + FactoryList factory; + + /** The time we next call our ping timeout and reg timeout checks + */ + time_t next_call; + + /** Global cull list, will be processed on next iteration + */ + CullList GlobalCulls; + + /** Get the current time + * Because this only calls time() once every time around the mainloop, + * it is much faster than calling time() directly. + * @param delta True to use the delta as an offset, false otherwise + * @return The current time as an epoch value (time_t) + */ + time_t Time(bool delta = false); + + /** Set the time offset in seconds + * This offset is added to Time() to offset the system time by the specified + * number of seconds. + * @param delta The number of seconds to offset + * @return The old time delta + */ + int SetTimeDelta(int delta); + + /** Add a user to the local clone map + * @param user The user to add + */ + void AddLocalClone(userrec* user); + + /** Add a user to the global clone map + * @param user The user to add + */ + void AddGlobalClone(userrec* user); + + /** Number of users with a certain mode set on them + */ + int ModeCount(const char mode); + + /** Get the time offset in seconds + * @return The current time delta (in seconds) + */ + int GetTimeDelta(); + + /** Process a user whos socket has been flagged as active + * @param cu The user to process + * @return There is no actual return value, however upon exit, the user 'cu' may have been + * marked for deletion in the global CullList. + */ + void ProcessUser(userrec* cu); + + /** Get the total number of currently loaded modules + * @return The number of loaded modules + */ + int GetModuleCount(); + + /** Find a module by name, and return a Module* to it. + * This is preferred over iterating the module lists yourself. + * @param name The module name to look up + * @return A pointer to the module, or NULL if the module cannot be found + */ + Module* FindModule(const std::string &name); + + /** Bind all ports specified in the configuration file. + * @param bail True if the function should bail back to the shell on failure + * @param found_ports The actual number of ports found in the config, as opposed to the number actually bound + * @return The number of ports actually bound without error + */ + int BindPorts(bool bail, int &found_ports, FailedPortList &failed_ports); + + /** Binds a socket on an already open file descriptor + * @param sockfd A valid file descriptor of an open socket + * @param port The port number to bind to + * @param addr The address to bind to (IP only) + * @return True if the port was bound successfully + */ + bool BindSocket(int sockfd, int port, char* addr, bool dolisten = true); + + /** Adds a server name to the list of servers we've seen + * @param The servername to add + */ + void AddServerName(const std::string &servername); + + /** Finds a cached char* pointer of a server name, + * This is used to optimize userrec by storing only the pointer to the name + * @param The servername to find + * @return A pointer to this name, gauranteed to never become invalid + */ + const char* FindServerNamePtr(const std::string &servername); + + /** Returns true if we've seen the given server name before + * @param The servername to find + * @return True if we've seen this server name before + */ + bool FindServerName(const std::string &servername); + + /** Gets the GECOS (description) field of the given server. + * If the servername is not that of the local server, the name + * is passed to handling modules which will attempt to determine + * the GECOS that bleongs to the given servername. + * @param servername The servername to find the description of + * @return The description of this server, or of the local server + */ + std::string GetServerDescription(const char* servername); + + /** Write text to all opers connected to this server + * @param text The text format string + * @param ... Format args + */ + void WriteOpers(const char* text, ...); + + /** Write text to all opers connected to this server + * @param text The text to send + */ + void WriteOpers(const std::string &text); + + /** Find a nickname in the nick hash + * @param nick The nickname to find + * @return A pointer to the user, or NULL if the user does not exist + */ + userrec* FindNick(const std::string &nick); + + /** Find a nickname in the nick hash + * @param nick The nickname to find + * @return A pointer to the user, or NULL if the user does not exist + */ + userrec* FindNick(const char* nick); + + /** Find a channel in the channels hash + * @param chan The channel to find + * @return A pointer to the channel, or NULL if the channel does not exist + */ + chanrec* FindChan(const std::string &chan); + + /** Find a channel in the channels hash + * @param chan The channel to find + * @return A pointer to the channel, or NULL if the channel does not exist + */ + chanrec* FindChan(const char* chan); + + /** Called by the constructor to load all modules from the config file. + */ + void LoadAllModules(); + + /** Check for a 'die' tag in the config file, and abort if found + * @return Depending on the configuration, this function may never return + */ + void CheckDie(); + + /** Check we aren't running as root, and exit if we are + * @return Depending on the configuration, this function may never return + */ + void CheckRoot(); + + /** Determine the right path for, and open, the logfile + * @param argv The argv passed to main() initially, used to calculate program path + * @param argc The argc passed to main() initially, used to calculate program path + */ + void OpenLog(char** argv, int argc); + + /** Close the currently open log file + */ + void CloseLog(); + + /** Send a server notice to all local users + * @param text The text format string to send + * @param ... The format arguments + */ + void ServerNoticeAll(char* text, ...); + + /** Send a server message (PRIVMSG) to all local users + * @param text The text format string to send + * @param ... The format arguments + */ + void ServerPrivmsgAll(char* text, ...); + + /** Send text to all users with a specific set of modes + * @param modes The modes to check against, without a +, e.g. 'og' + * @param flags one of WM_OR or WM_AND. If you specify WM_OR, any one of the + * mode characters in the first parameter causes receipt of the message, and + * if you specify WM_OR, all the modes must be present. + * @param text The text format string to send + * @param ... The format arguments + */ + void WriteMode(const char* modes, int flags, const char* text, ...); + + /** Return true if a channel name is valid + * @param chname A channel name to verify + * @return True if the name is valid + */ + bool IsChannel(const char *chname); + + /** Rehash the local server + * @param status This value is unused, and required for signal handler functions + */ + static void Rehash(int status); + + /** Causes the server to exit after unloading modules and + * closing all open file descriptors. + * + * @param The exit code to give to the operating system + * (See the ExitStatus enum for valid values) + */ + static void Exit(int status); + + /** Causes the server to exit immediately with exit code 0. + * The status code is required for signal handlers, and ignored. + */ + static void QuickExit(int status); + + /** Return a count of users, unknown and known connections + * @return The number of users + */ + int UserCount(); + + /** Return a count of fully registered connections only + * @return The number of registered users + */ + int RegisteredUserCount(); + + /** Return a count of invisible (umode +i) users only + * @return The number of invisible users + */ + int InvisibleUserCount(); + + /** Return a count of opered (umode +o) users only + * @return The number of opers + */ + int OperCount(); + + /** Return a count of unregistered (before NICK/USER) users only + * @return The number of unregistered (unknown) connections + */ + int UnregisteredUserCount(); + + /** Return a count of channels on the network + * @return The number of channels + */ + long ChannelCount(); + + /** Return a count of local users on this server only + * @return The number of local users + */ + long LocalUserCount(); + + /** Send an error notice to all local users, opered and unopered + * @param s The error string to send + */ + void SendError(const std::string &s); + + /** For use with Module::Prioritize(). + * When the return value of this function is returned from + * Module::Prioritize(), this specifies that the module wishes + * to be ordered exactly BEFORE 'modulename'. For more information + * please see Module::Prioritize(). + * @param modulename The module your module wants to be before in the call list + * @returns a priority ID which the core uses to relocate the module in the list + */ + long PriorityBefore(const std::string &modulename); + + /** For use with Module::Prioritize(). + * When the return value of this function is returned from + * Module::Prioritize(), this specifies that the module wishes + * to be ordered exactly AFTER 'modulename'. For more information please + * see Module::Prioritize(). + * @param modulename The module your module wants to be after in the call list + * @returns a priority ID which the core uses to relocate the module in the list + */ + long PriorityAfter(const std::string &modulename); + + /** Publish a 'feature'. + * There are two ways for a module to find another module it depends on. + * Either by name, using InspIRCd::FindModule, or by feature, using this + * function. A feature is an arbitary string which identifies something this + * module can do. For example, if your module provides SSL support, but other + * modules provide SSL support too, all the modules supporting SSL should + * publish an identical 'SSL' feature. This way, any module requiring use + * of SSL functions can just look up the 'SSL' feature using FindFeature, + * then use the module pointer they are given. + * @param FeatureName The case sensitive feature name to make available + * @param Mod a pointer to your module class + * @returns True on success, false if the feature is already published by + * another module. + */ + bool PublishFeature(const std::string &FeatureName, Module* Mod); + + /** Publish a module to an 'interface'. + * Modules which implement the same interface (the same way of communicating + * with other modules) can publish themselves to an interface, using this + * method. When they do so, they become part of a list of related or + * compatible modules, and a third module may then query for that list + * and know that all modules within that list offer the same API. + * A prime example of this is the hashing modules, which all accept the + * same types of Request class. Consider this to be similar to PublishFeature, + * except for that multiple modules may publish the same 'feature'. + * @param InterfaceName The case sensitive interface name to make available + * @param Mod a pointer to your module class + * @returns True on success, false on failure (there are currently no failure + * cases) + */ + bool PublishInterface(const std::string &InterfaceName, Module* Mod); + + /** Return a pair saying how many other modules are currently using the + * interfaces provided by module m. + * @param m The module to count usage for + * @return A pair, where the first value is the number of uses of the interface, + * and the second value is the interface name being used. + */ + std::pair<int,std::string> GetInterfaceInstanceCount(Module* m); + + /** Mark your module as using an interface. + * If you mark your module as using an interface, then that interface + * module may not unload until your module has unloaded first. + * This can be used to prevent crashes by ensuring code you depend on + * is always in memory while your module is active. + * @param InterfaceName The interface to use + */ + void UseInterface(const std::string &InterfaceName); + + /** Mark your module as finished with an interface. + * If you used UseInterface() above, you should use this method when + * your module is finished with the interface (usually in its destructor) + * to allow the modules which implement the given interface to be unloaded. + * @param InterfaceName The interface you are finished with using. + */ + void DoneWithInterface(const std::string &InterfaceName); + + /** Unpublish a 'feature'. + * When your module exits, it must call this method for every feature it + * is providing so that the feature table is cleaned up. + * @param FeatureName the feature to remove + */ + bool UnpublishFeature(const std::string &FeatureName); + + /** Unpublish your module from an interface + * When your module exits, it must call this method for every interface + * it is part of so that the interfaces table is cleaned up. Only when + * the last item is deleted from an interface does the interface get + * removed. + * @param InterfaceName the interface to be removed from + * @param Mod The module to remove from the interface list + */ + bool UnpublishInterface(const std::string &InterfaceName, Module* Mod); + + /** Find a 'feature'. + * There are two ways for a module to find another module it depends on. + * Either by name, using InspIRCd::FindModule, or by feature, using the + * InspIRCd::PublishFeature method. A feature is an arbitary string which + * identifies something this module can do. For example, if your module + * provides SSL support, but other modules provide SSL support too, all + * the modules supporting SSL should publish an identical 'SSL' feature. + * To find a module capable of providing the feature you want, simply + * call this method with the feature name you are looking for. + * @param FeatureName The feature name you wish to obtain the module for + * @returns A pointer to a valid module class on success, NULL on failure. + */ + Module* FindFeature(const std::string &FeatureName); + + /** Find an 'interface'. + * An interface is a list of modules which all implement the same API. + * @param InterfaceName The Interface you wish to obtain the module + * list of. + * @return A pointer to a deque of Module*, or NULL if the interface + * does not exist. + */ + modulelist* FindInterface(const std::string &InterfaceName); + + /** Given a pointer to a Module, return its filename + * @param m The module pointer to identify + * @return The module name or an empty string + */ + const std::string& GetModuleName(Module* m); + + /** Return true if a nickname is valid + * @param n A nickname to verify + * @return True if the nick is valid + */ + bool IsNick(const char* n); + + /** Return true if an ident is valid + * @param An ident to verify + * @return True if the ident is valid + */ + bool IsIdent(const char* n); + + /** Find a username by their file descriptor. + * It is preferred to use this over directly accessing the fd_ref_table array. + * @param socket The file descriptor of a user + * @return A pointer to the user if the user exists locally on this descriptor + */ + userrec* FindDescriptor(int socket); + + /** Add a new mode to this server's mode parser + * @param mh The modehandler to add + * @param modechar The mode character this modehandler handles + * @return True if the mode handler was added + */ + bool AddMode(ModeHandler* mh, const unsigned char modechar); + + /** Add a new mode watcher to this server's mode parser + * @param mw The modewatcher to add + * @return True if the modewatcher was added + */ + bool AddModeWatcher(ModeWatcher* mw); + + /** Delete a mode watcher from this server's mode parser + * @param mw The modewatcher to delete + * @return True if the modewatcher was deleted + */ + bool DelModeWatcher(ModeWatcher* mw); + + /** Add a dns Resolver class to this server's active set + * @param r The resolver to add + * @param cached If this value is true, then the cache will + * be searched for the DNS result, immediately. If the value is + * false, then a request will be sent to the nameserver, and the + * result will not be immediately available. You should usually + * use the boolean value which you passed to the Resolver + * constructor, which Resolver will set appropriately depending + * on if cached results are available and haven't expired. It is + * however safe to force this value to false, forcing a remote DNS + * lookup, but not an update of the cache. + * @return True if the operation completed successfully. Note that + * if this method returns true, you should not attempt to access + * the resolver class you pass it after this call, as depending upon + * the request given, the object may be deleted! + */ + bool AddResolver(Resolver* r, bool cached); + + /** Add a command to this server's command parser + * @param f A command_t command handler object to add + * @throw ModuleException Will throw ModuleExcption if the command already exists + */ + void AddCommand(command_t *f); + + /** Send a modechange. + * The parameters provided are identical to that sent to the + * handler for class cmd_mode. + * @param parameters The mode parameters + * @param pcnt The number of items you have given in the first parameter + * @param user The user to send error messages to + */ + void SendMode(const char **parameters, int pcnt, userrec *user); + + /** Match two strings using pattern matching. + * This operates identically to the global function match(), + * except for that it takes std::string arguments rather than + * const char* ones. + * @param sliteral The literal string to match against + * @param spattern The pattern to match against. CIDR and globs are supported. + */ + bool MatchText(const std::string &sliteral, const std::string &spattern); + + /** Call the handler for a given command. + * @param commandname The command whos handler you wish to call + * @param parameters The mode parameters + * @param pcnt The number of items you have given in the first parameter + * @param user The user to execute the command as + * @return True if the command handler was called successfully + */ + CmdResult CallCommandHandler(const std::string &commandname, const char** parameters, int pcnt, userrec* user); + + /** Return true if the command is a module-implemented command and the given parameters are valid for it + * @param parameters The mode parameters + * @param pcnt The number of items you have given in the first parameter + * @param user The user to test-execute the command as + * @return True if the command handler is a module command, and there are enough parameters and the user has permission to the command + */ + bool IsValidModuleCommand(const std::string &commandname, int pcnt, userrec* user); + + /** Add a gline and apply it + * @param duration How long the line should last + * @param source Who set the line + * @param reason The reason for the line + * @param hostmask The hostmask to set the line against + */ + void AddGLine(long duration, const std::string &source, const std::string &reason, const std::string &hostmask); + + /** Add a qline and apply it + * @param duration How long the line should last + * @param source Who set the line + * @param reason The reason for the line + * @param nickname The nickmask to set the line against + */ + void AddQLine(long duration, const std::string &source, const std::string &reason, const std::string &nickname); + + /** Add a zline and apply it + * @param duration How long the line should last + * @param source Who set the line + * @param reason The reason for the line + * @param ipaddr The ip-mask to set the line against + */ + void AddZLine(long duration, const std::string &source, const std::string &reason, const std::string &ipaddr); + + /** Add a kline and apply it + * @param duration How long the line should last + * @param source Who set the line + * @param reason The reason for the line + * @param hostmask The hostmask to set the line against + */ + void AddKLine(long duration, const std::string &source, const std::string &reason, const std::string &hostmask); + + /** Add an eline + * @param duration How long the line should last + * @param source Who set the line + * @param reason The reason for the line + * @param hostmask The hostmask to set the line against + */ + void AddELine(long duration, const std::string &source, const std::string &reason, const std::string &hostmask); + + /** Delete a gline + * @param hostmask The gline to delete + * @return True if the item was removed + */ + bool DelGLine(const std::string &hostmask); + + /** Delete a qline + * @param nickname The qline to delete + * @return True if the item was removed + */ + bool DelQLine(const std::string &nickname); + + /** Delete a zline + * @param ipaddr The zline to delete + * @return True if the item was removed + */ + bool DelZLine(const std::string &ipaddr); + + /** Delete a kline + * @param hostmask The kline to delete + * @return True if the item was removed + */ + bool DelKLine(const std::string &hostmask); + + /** Delete an eline + * @param hostmask The kline to delete + * @return True if the item was removed + */ + bool DelELine(const std::string &hostmask); + + /** Return true if the given parameter is a valid nick!user\@host mask + * @param mask A nick!user\@host masak to match against + * @return True i the mask is valid + */ + bool IsValidMask(const std::string &mask); + + /** Rehash the local server + */ + void RehashServer(); + + /** Return the channel whos index number matches that provided + * @param The index number of the channel to fetch + * @return A channel record, or NUll if index < 0 or index >= InspIRCd::ChannelCount() + */ + chanrec* GetChannelIndex(long index); + + /** Dump text to a user target, splitting it appropriately to fit + * @param User the user to dump the text to + * @param LinePrefix text to prefix each complete line with + * @param TextStream the text to send to the user + */ + void DumpText(userrec* User, const std::string &LinePrefix, stringstream &TextStream); + + /** Check if the given nickmask matches too many users, send errors to the given user + * @param nick A nickmask to match against + * @param user A user to send error text to + * @return True if the nick matches too many users + */ + bool NickMatchesEveryone(const std::string &nick, userrec* user); + + /** Check if the given IP mask matches too many users, send errors to the given user + * @param ip An ipmask to match against + * @param user A user to send error text to + * @return True if the ip matches too many users + */ + bool IPMatchesEveryone(const std::string &ip, userrec* user); + + /** Check if the given hostmask matches too many users, send errors to the given user + * @param mask A hostmask to match against + * @param user A user to send error text to + * @return True if the host matches too many users + */ + bool HostMatchesEveryone(const std::string &mask, userrec* user); + + /** Calculate a duration in seconds from a string in the form 1y2w3d4h6m5s + * @param str A string containing a time in the form 1y2w3d4h6m5s + * (one year, two weeks, three days, four hours, six minutes and five seconds) + * @return The total number of seconds + */ + long Duration(const std::string &str); + + /** Attempt to compare an oper password to a string from the config file. + * This will be passed to handling modules which will compare the data + * against possible hashed equivalents in the input string. + * @param data The data from the config file + * @param input The data input by the oper + * @param tagnum the tag number of the oper's tag in the config file + * @return 0 if the strings match, 1 or -1 if they do not + */ + int OperPassCompare(const char* data,const char* input, int tagnum); + + /** Check if a given server is a uline. + * An empty string returns true, this is by design. + * @param server The server to check for uline status + * @return True if the server is a uline OR the string is empty + */ + bool ULine(const char* server); + + /** Returns true if the uline is 'silent' (doesnt generate + * remote connect notices etc). + */ + bool SilentULine(const char* server); + + /** Returns the subversion revision ID of this ircd + * @return The revision ID or an empty string + */ + std::string GetRevision(); + + /** Returns the full version string of this ircd + * @return The version string + */ + std::string GetVersionString(); + + /** Attempt to write the process id to a given file + * @param filename The PID file to attempt to write to + * @return This function may bail if the file cannot be written + */ + void WritePID(const std::string &filename); + + /** Returns text describing the last module error + * @return The last error message to occur + */ + char* ModuleError(); + + /** Load a given module file + * @param filename The file to load + * @return True if the module was found and loaded + */ + bool LoadModule(const char* filename); + + /** Unload a given module file + * @param filename The file to unload + * @return True if the module was unloaded + */ + bool UnloadModule(const char* filename); + + /** This constructor initialises all the subsystems and reads the config file. + * @param argc The argument count passed to main() + * @param argv The argument list passed to main() + * @throw <anything> If anything is thrown from here and makes it to + * you, you should probably just give up and go home. Yes, really. + * It's that bad. Higher level classes should catch any non-fatal exceptions. + */ + InspIRCd(int argc, char** argv); + + /** Do one iteration of the mainloop + * @param process_module_sockets True if module sockets are to be processed + * this time around the event loop. The is the default. + */ + void DoOneIteration(bool process_module_sockets = true); + + /** Output a log message to the ircd.log file + * The text will only be output if the current loglevel + * is less than or equal to the level you provide + * @param level A log level from the DebugLevel enum + * @param text Format string of to write to the log + * @param ... Format arguments of text to write to the log + */ + void Log(int level, const char* text, ...); + + /** Output a log message to the ircd.log file + * The text will only be output if the current loglevel + * is less than or equal to the level you provide + * @param level A log level from the DebugLevel enum + * @param text Text to write to the log + */ + void Log(int level, const std::string &text); + + /** Send a line of WHOIS data to a user. + * @param user user to send the line to + * @param dest user being WHOISed + * @param numeric Numeric to send + * @param text Text of the numeric + */ + void SendWhoisLine(userrec* user, userrec* dest, int numeric, const std::string &text); + + /** Send a line of WHOIS data to a user. + * @param user user to send the line to + * @param dest user being WHOISed + * @param numeric Numeric to send + * @param format Format string for the numeric + * @param ... Parameters for the format string + */ + void SendWhoisLine(userrec* user, userrec* dest, int numeric, const char* format, ...); + + /** Quit a user for excess flood, and if they are not + * fully registered yet, temporarily zline their IP. + * @param current user to quit + */ + void FloodQuitUser(userrec* current); + + /** Restart the server. + * This function will not return. If an error occurs, + * it will throw an instance of CoreException. + * @param reason The restart reason to show to all clients + * @throw CoreException An instance of CoreException indicating the error from execv(). + */ + void Restart(const std::string &reason); + + /** Prepare the ircd for restart or shutdown. + * This function unloads all modules which can be unloaded, + * closes all open sockets, and closes the logfile. + */ + void Cleanup(); + + /** This copies the user and channel hash_maps into new hash maps. + * This frees memory used by the hash_map allocator (which it neglects + * to free, most of the time, using tons of ram) + */ + void RehashUsersAndChans(); + + /** Resets the cached max bans value on all channels. + * Called by rehash. + */ + void ResetMaxBans(); + + /** Return a time_t as a human-readable string. + */ + std::string TimeString(time_t curtime); + + /** Begin execution of the server. + * NOTE: this function NEVER returns. Internally, + * after performing some initialisation routines, + * it will repeatedly call DoOneIteration in a loop. + * @return The return value for this function is undefined. + */ + int Run(); +}; + +#endif + diff --git a/include/inspsocket.h b/include/inspsocket.h index 98fbc018f..d165d64f2 100644 --- a/include/inspsocket.h +++ b/include/inspsocket.h @@ -1 +1,437 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __INSP_SOCKET_H__
#define __INSP_SOCKET_H__
#include <sstream>
#include <string>
#include <deque>
#include "dns.h"
#include "inspircd_config.h"
#include "socket.h"
#include "inspsocket.h"
#include "timer.h"
/**
* States which a socket may be in
*/
enum InspSocketState
{
/** Socket disconnected */
I_DISCONNECTED,
/** Socket connecting */
I_CONNECTING,
/** Socket fully connected */
I_CONNECTED,
/** Socket listening for connections */
I_LISTENING,
/** Socket has an error */
I_ERROR
};
/**
* Error types which a socket may exhibit
*/
enum InspSocketError
{
/** Socket connect timed out */
I_ERR_TIMEOUT,
/** Socket could not be created */
I_ERR_SOCKET,
/** Socket could not connect (refused) */
I_ERR_CONNECT,
/** Socket could not bind to local port/ip */
I_ERR_BIND,
/** Socket could not reslve host (depreciated) */
I_ERR_RESOLVE,
/** Socket could not write data */
I_ERR_WRITE,
/** No more file descriptors left to create socket! */
I_ERR_NOMOREFDS
};
/* Required forward declarations */
class InspSocket;
class InspIRCd;
using irc::sockets::insp_sockaddr;
using irc::sockets::insp_inaddr;
using irc::sockets::insp_ntoa;
using irc::sockets::insp_aton;
/** Used to time out socket connections
*/
class CoreExport SocketTimeout : public InspTimer
{
private:
/** InspSocket the class is attached to
*/
InspSocket* sock;
/** Server instance creating the timeout class
*/
InspIRCd* ServerInstance;
/** File descriptor of class this is attached to
*/
int sfd;
public:
/** Create a socket timeout class
* @param fd File descriptor of InspSocket
* @pram Instance server instance to attach to
* @param thesock InspSocket to attach to
* @param secs_from_now Seconds from now to time out
* @param now The current time
*/
SocketTimeout(int fd, InspIRCd* Instance, InspSocket* thesock, long secs_from_now, time_t now) : InspTimer(secs_from_now, now), sock(thesock), ServerInstance(Instance), sfd(fd) { };
/** Handle tick event
*/
virtual void Tick(time_t now);
};
/**
* InspSocket is an extendable socket class which modules
* can use for TCP socket support. It is fully integrated
* into InspIRCds socket loop and attaches its sockets to
* the core's instance of the SocketEngine class, meaning
* that any sockets you create have the same power and
* abilities as a socket created by the core itself.
* To use InspSocket, you must inherit a class from it,
* and use the InspSocket constructors to establish connections
* and bindings.
*/
class CoreExport InspSocket : public EventHandler
{
public:
/**
* Bind IP
*/
std::string cbindip;
/**
* Is hooked by a module for low level IO
*/
bool IsIOHooked;
/**
* Instance we were created by
*/
InspIRCd* Instance;
/**
* Timeout class or NULL
*/
SocketTimeout* Timeout;
/**
* Timeout length
*/
unsigned long timeout_val;
/**
* Socket output buffer (binary safe)
*/
std::deque<std::string> outbuffer;
/**
* The hostname connected to
*/
char host[MAXBUF];
/**
* The port connected to, or the port
* this socket is listening on
*/
int port;
/**
* The state for this socket, either
* listening, connecting, connected
* or error.
*/
InspSocketState state;
/**
* This value is true if the
* socket has timed out.
*/
bool timeout;
/**
* Socket input buffer, used by read(). The class which
* extends InspSocket is expected to implement an extendable
* buffer which can grow much larger than 64k,
* this buffer is just designed to be temporary storage.
* space.
*/
char ibuf[65535];
/**
* The IP address being connected
* to stored in string form for
* easy retrieval by accessors.
*/
char IP[MAXBUF];
/**
* Used by accept() to indicate the
* sizes of the sockaddr_in structures
*/
socklen_t length;
/** Flushes the write buffer
*/
bool FlushWriteBuffer();
/** Set the queue sizes
* This private method sets the operating system queue
* sizes for this socket to 65535 so that it can queue
* more information without application-level queueing
* which was required in older software.
*/
void SetQueues(int nfd);
/** When the socket has been marked as closing, this flag
* will be set to true, then the next time the socket is
* examined, the socket is deleted and closed.
*/
bool ClosePending;
/** Set to true when we're waiting for a write event.
* If this is true and a write event comes in, we
* call the write instead of the read method.
*/
bool WaitingForWriteEvent;
/**
* Bind to an address
* @param ip IP to bind to
* @return True is the binding succeeded
*/
bool BindAddr(const std::string &ip);
/**
* The default constructor does nothing
* and should not be used.
*/
InspSocket(InspIRCd* SI);
/**
* This constructor is used to associate
* an existing connecting with an InspSocket
* class. The given file descriptor must be
* valid, and when initialized, the InspSocket
* will be set with the given IP address
* and placed in CONNECTED state.
*/
InspSocket(InspIRCd* SI, int newfd, const char* ip);
/**
* This constructor is used to create a new
* socket, either listening for connections, or an outbound connection to another host.
* Note that if you specify a hostname in the 'ipaddr' parameter, this class will not
* connect. You must resolve your hostnames before passing them to InspSocket. To do so,
* you should use the nonblocking class 'Resolver'.
* @param ipaddr The IP to connect to, or bind to
* @param port The port number to connect to, or bind to
* @param listening true to listen on the given host:port pair, or false to connect to them
* @param maxtime Number of seconds to wait, if connecting, before the connection times out and an OnTimeout() event is generated
* @param connectbindip When creating an outbound connection, the IP to bind the connection to. If not defined, the port is not bound.
* @return On exit, GetState() returns I_ERROR if an error occured, and errno can be used to read the socket error.
*/
InspSocket(InspIRCd* SI, const std::string &ipaddr, int port, bool listening, unsigned long maxtime, const std::string &connectbindip = "");
/**
* This method is called when an outbound
* connection on your socket is completed.
* @return false to abort the connection, true to continue
*/
virtual bool OnConnected();
/**
* This method is called when an error occurs.
* A closed socket in itself is not an error,
* however errors also generate close events.
* @param e The error type which occured
*/
virtual void OnError(InspSocketError e);
/**
* When an established connection is terminated,
* the OnDisconnect method is triggered.
*/
virtual int OnDisconnect();
/**
* When there is data waiting to be read on a
* socket, the OnDataReady() method is called.
* Within this method, you *MUST* call the Read()
* method to read any pending data. At its lowest
* level, this event is signalled by the core via
* the socket engine. If you return false from this
* function, the core removes your socket from its
* list and erases it from the socket engine, then
* calls InspSocket::Close() and deletes it.
* @return false to close the socket
*/
virtual bool OnDataReady();
/**
* When it is ok to write to the socket, and a
* write event was requested, this method is
* triggered. Within this method you should call
* write() or send() etc, to send data to the
* other end of the socket. Further write events
* will not be triggered unless you call WantWrite().
* @return false to close the socket
*/
virtual bool OnWriteReady();
/**
* When an outbound connection fails, and the
* attempt times out, you will receive this event.
* The method will trigger once maxtime seconds are
* reached (as given in the constructor) just
* before the socket's descriptor is closed.
* A failed DNS lookup may cause this event if
* the DNS server is not responding, as well as
* a failed connect() call, because DNS lookups are
* nonblocking as implemented by this class.
*/
virtual void OnTimeout();
/**
* Whenever close() is called, OnClose() will be
* called first. Please note that this means
* OnClose will be called alongside OnError(),
* OnTimeout(), and Close(), and also when
* cancelling a listening socket by calling
* the destructor indirectly.
*/
virtual void OnClose();
/**
* Reads all pending bytes from the socket
* into a char* array which can be up to
* 16 kilobytes in length.
*/
virtual char* Read();
/**
* Returns the IP address associated with
* this connection, or an empty string if
* no IP address exists.
*/
std::string GetIP();
/**
* Writes a std::string to the socket. No carriage
* returns or linefeeds are appended to the string.
* @param data The data to send
*/
virtual int Write(const std::string &data);
/**
* If your socket is a listening socket, when a new
* connection comes in on the socket this method will
* be called. Given the new file descriptor in the
* parameters, and the IP, it is recommended you copy
* them to a new instance of your socket class,
* e.g.:
*
* MySocket* newsocket = new MySocket(newfd,ip);
*
* Once you have done this, you can then associate the
* new socket with the core using Server::AddSocket().
*/
virtual int OnIncomingConnection(int newfd, char* ip);
/**
* Changes the socket's state. The core uses this
* to change socket states, and you should not call
* it directly.
*/
void SetState(InspSocketState s);
/**
* Call this to receive the next write event
* that comes along for this fd to the OnWriteReady
* method.
*/
void WantWrite();
/**
* Returns the current socket state.
*/
InspSocketState GetState();
/**
* Only the core should call this function.
* When called, it is assumed the socket is ready
* to read data, and the method call routes the
* event to the various methods of InspSocket
* for you to handle. This can also cause the
* socket's state to change.
*/
bool Poll();
/**
* This method returns the socket's file descriptor
* as assigned by the operating system, or -1
* if no descriptor has been assigned.
*/
int GetFd();
/**
* This method causes the socket to close, and may
* also be triggered by other methods such as OnTimeout
* and OnError.
*/
virtual void Close();
/**
* The destructor may implicitly call OnClose(), and
* will close() and shutdown() the file descriptor
* used for this socket.
*/
virtual ~InspSocket();
/**
* This method attempts to connect to a hostname.
* This only occurs on a non-listening socket. This
* method is asyncronous.
*/
virtual bool DoConnect();
/**
* This method marks the socket closed.
* The next time the core examines a socket marked
* as closed, the socket will be closed and the
* memory reclaimed.
*
* NOTE: This method is DEPRECIATED and will be
* ignored if called!
*/
void MarkAsClosed();
/** Handle event from EventHandler parent class
*/
void HandleEvent(EventType et, int errornum = 0);
/** Returns true if this socket is readable
*/
bool Readable();
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __INSP_SOCKET_H__ +#define __INSP_SOCKET_H__ + +#include <sstream> +#include <string> +#include <deque> +#include "dns.h" +#include "inspircd_config.h" +#include "socket.h" +#include "inspsocket.h" +#include "timer.h" + +/** + * States which a socket may be in + */ +enum InspSocketState +{ + /** Socket disconnected */ + I_DISCONNECTED, + /** Socket connecting */ + I_CONNECTING, + /** Socket fully connected */ + I_CONNECTED, + /** Socket listening for connections */ + I_LISTENING, + /** Socket has an error */ + I_ERROR +}; + +/** + * Error types which a socket may exhibit + */ +enum InspSocketError +{ + /** Socket connect timed out */ + I_ERR_TIMEOUT, + /** Socket could not be created */ + I_ERR_SOCKET, + /** Socket could not connect (refused) */ + I_ERR_CONNECT, + /** Socket could not bind to local port/ip */ + I_ERR_BIND, + /** Socket could not reslve host (depreciated) */ + I_ERR_RESOLVE, + /** Socket could not write data */ + I_ERR_WRITE, + /** No more file descriptors left to create socket! */ + I_ERR_NOMOREFDS +}; + +/* Required forward declarations */ +class InspSocket; +class InspIRCd; + +using irc::sockets::insp_sockaddr; +using irc::sockets::insp_inaddr; +using irc::sockets::insp_ntoa; +using irc::sockets::insp_aton; + +/** Used to time out socket connections + */ +class CoreExport SocketTimeout : public InspTimer +{ + private: + /** InspSocket the class is attached to + */ + InspSocket* sock; + /** Server instance creating the timeout class + */ + InspIRCd* ServerInstance; + /** File descriptor of class this is attached to + */ + int sfd; + public: + /** Create a socket timeout class + * @param fd File descriptor of InspSocket + * @pram Instance server instance to attach to + * @param thesock InspSocket to attach to + * @param secs_from_now Seconds from now to time out + * @param now The current time + */ + SocketTimeout(int fd, InspIRCd* Instance, InspSocket* thesock, long secs_from_now, time_t now) : InspTimer(secs_from_now, now), sock(thesock), ServerInstance(Instance), sfd(fd) { }; + /** Handle tick event + */ + virtual void Tick(time_t now); +}; + +/** + * InspSocket is an extendable socket class which modules + * can use for TCP socket support. It is fully integrated + * into InspIRCds socket loop and attaches its sockets to + * the core's instance of the SocketEngine class, meaning + * that any sockets you create have the same power and + * abilities as a socket created by the core itself. + * To use InspSocket, you must inherit a class from it, + * and use the InspSocket constructors to establish connections + * and bindings. + */ +class CoreExport InspSocket : public EventHandler +{ + public: + + /** + * Bind IP + */ + std::string cbindip; + + /** + * Is hooked by a module for low level IO + */ + bool IsIOHooked; + + /** + * Instance we were created by + */ + InspIRCd* Instance; + + /** + * Timeout class or NULL + */ + SocketTimeout* Timeout; + + /** + * Timeout length + */ + unsigned long timeout_val; + + /** + * Socket output buffer (binary safe) + */ + std::deque<std::string> outbuffer; + + /** + * The hostname connected to + */ + char host[MAXBUF]; + + /** + * The port connected to, or the port + * this socket is listening on + */ + int port; + + /** + * The state for this socket, either + * listening, connecting, connected + * or error. + */ + InspSocketState state; + + /** + * This value is true if the + * socket has timed out. + */ + bool timeout; + + /** + * Socket input buffer, used by read(). The class which + * extends InspSocket is expected to implement an extendable + * buffer which can grow much larger than 64k, + * this buffer is just designed to be temporary storage. + * space. + */ + char ibuf[65535]; + + /** + * The IP address being connected + * to stored in string form for + * easy retrieval by accessors. + */ + char IP[MAXBUF]; + + /** + * Used by accept() to indicate the + * sizes of the sockaddr_in structures + */ + socklen_t length; + + /** Flushes the write buffer + */ + bool FlushWriteBuffer(); + + /** Set the queue sizes + * This private method sets the operating system queue + * sizes for this socket to 65535 so that it can queue + * more information without application-level queueing + * which was required in older software. + */ + void SetQueues(int nfd); + + /** When the socket has been marked as closing, this flag + * will be set to true, then the next time the socket is + * examined, the socket is deleted and closed. + */ + bool ClosePending; + + /** Set to true when we're waiting for a write event. + * If this is true and a write event comes in, we + * call the write instead of the read method. + */ + bool WaitingForWriteEvent; + + /** + * Bind to an address + * @param ip IP to bind to + * @return True is the binding succeeded + */ + bool BindAddr(const std::string &ip); + + /** + * The default constructor does nothing + * and should not be used. + */ + InspSocket(InspIRCd* SI); + + /** + * This constructor is used to associate + * an existing connecting with an InspSocket + * class. The given file descriptor must be + * valid, and when initialized, the InspSocket + * will be set with the given IP address + * and placed in CONNECTED state. + */ + InspSocket(InspIRCd* SI, int newfd, const char* ip); + + /** + * This constructor is used to create a new + * socket, either listening for connections, or an outbound connection to another host. + * Note that if you specify a hostname in the 'ipaddr' parameter, this class will not + * connect. You must resolve your hostnames before passing them to InspSocket. To do so, + * you should use the nonblocking class 'Resolver'. + * @param ipaddr The IP to connect to, or bind to + * @param port The port number to connect to, or bind to + * @param listening true to listen on the given host:port pair, or false to connect to them + * @param maxtime Number of seconds to wait, if connecting, before the connection times out and an OnTimeout() event is generated + * @param connectbindip When creating an outbound connection, the IP to bind the connection to. If not defined, the port is not bound. + * @return On exit, GetState() returns I_ERROR if an error occured, and errno can be used to read the socket error. + */ + InspSocket(InspIRCd* SI, const std::string &ipaddr, int port, bool listening, unsigned long maxtime, const std::string &connectbindip = ""); + + /** + * This method is called when an outbound + * connection on your socket is completed. + * @return false to abort the connection, true to continue + */ + virtual bool OnConnected(); + + /** + * This method is called when an error occurs. + * A closed socket in itself is not an error, + * however errors also generate close events. + * @param e The error type which occured + */ + virtual void OnError(InspSocketError e); + + /** + * When an established connection is terminated, + * the OnDisconnect method is triggered. + */ + virtual int OnDisconnect(); + + /** + * When there is data waiting to be read on a + * socket, the OnDataReady() method is called. + * Within this method, you *MUST* call the Read() + * method to read any pending data. At its lowest + * level, this event is signalled by the core via + * the socket engine. If you return false from this + * function, the core removes your socket from its + * list and erases it from the socket engine, then + * calls InspSocket::Close() and deletes it. + * @return false to close the socket + */ + virtual bool OnDataReady(); + + /** + * When it is ok to write to the socket, and a + * write event was requested, this method is + * triggered. Within this method you should call + * write() or send() etc, to send data to the + * other end of the socket. Further write events + * will not be triggered unless you call WantWrite(). + * @return false to close the socket + */ + virtual bool OnWriteReady(); + + /** + * When an outbound connection fails, and the + * attempt times out, you will receive this event. + * The method will trigger once maxtime seconds are + * reached (as given in the constructor) just + * before the socket's descriptor is closed. + * A failed DNS lookup may cause this event if + * the DNS server is not responding, as well as + * a failed connect() call, because DNS lookups are + * nonblocking as implemented by this class. + */ + virtual void OnTimeout(); + + /** + * Whenever close() is called, OnClose() will be + * called first. Please note that this means + * OnClose will be called alongside OnError(), + * OnTimeout(), and Close(), and also when + * cancelling a listening socket by calling + * the destructor indirectly. + */ + virtual void OnClose(); + + /** + * Reads all pending bytes from the socket + * into a char* array which can be up to + * 16 kilobytes in length. + */ + virtual char* Read(); + + /** + * Returns the IP address associated with + * this connection, or an empty string if + * no IP address exists. + */ + std::string GetIP(); + + /** + * Writes a std::string to the socket. No carriage + * returns or linefeeds are appended to the string. + * @param data The data to send + */ + virtual int Write(const std::string &data); + + /** + * If your socket is a listening socket, when a new + * connection comes in on the socket this method will + * be called. Given the new file descriptor in the + * parameters, and the IP, it is recommended you copy + * them to a new instance of your socket class, + * e.g.: + * + * MySocket* newsocket = new MySocket(newfd,ip); + * + * Once you have done this, you can then associate the + * new socket with the core using Server::AddSocket(). + */ + virtual int OnIncomingConnection(int newfd, char* ip); + + /** + * Changes the socket's state. The core uses this + * to change socket states, and you should not call + * it directly. + */ + void SetState(InspSocketState s); + + /** + * Call this to receive the next write event + * that comes along for this fd to the OnWriteReady + * method. + */ + void WantWrite(); + + /** + * Returns the current socket state. + */ + InspSocketState GetState(); + + /** + * Only the core should call this function. + * When called, it is assumed the socket is ready + * to read data, and the method call routes the + * event to the various methods of InspSocket + * for you to handle. This can also cause the + * socket's state to change. + */ + bool Poll(); + + /** + * This method returns the socket's file descriptor + * as assigned by the operating system, or -1 + * if no descriptor has been assigned. + */ + int GetFd(); + + /** + * This method causes the socket to close, and may + * also be triggered by other methods such as OnTimeout + * and OnError. + */ + virtual void Close(); + + /** + * The destructor may implicitly call OnClose(), and + * will close() and shutdown() the file descriptor + * used for this socket. + */ + virtual ~InspSocket(); + + /** + * This method attempts to connect to a hostname. + * This only occurs on a non-listening socket. This + * method is asyncronous. + */ + virtual bool DoConnect(); + + /** + * This method marks the socket closed. + * The next time the core examines a socket marked + * as closed, the socket will be closed and the + * memory reclaimed. + * + * NOTE: This method is DEPRECIATED and will be + * ignored if called! + */ + void MarkAsClosed(); + + /** Handle event from EventHandler parent class + */ + void HandleEvent(EventType et, int errornum = 0); + + /** Returns true if this socket is readable + */ + bool Readable(); +}; + +#endif + diff --git a/include/inspstring.h b/include/inspstring.h index 89abed94f..87024a9f8 100644 --- a/include/inspstring.h +++ b/include/inspstring.h @@ -1 +1,56 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __IN_INSPSTRING_H
#define __IN_INSPSTRING_H
#include "inspircd_config.h"
#include <string.h>
#include <cstddef>
#ifndef HAS_STRLCPY
/** strlcpy() implementation for systems that don't have it (linux) */
CoreExport size_t strlcpy(char *dst, const char *src, size_t siz);
/** strlcat() implementation for systems that don't have it (linux) */
CoreExport size_t strlcat(char *dst, const char *src, size_t siz);
#endif
/** charlcat() will append one character to a string using the same
* safety scemantics as strlcat().
* @param x The string to operate on
* @param y the character to append to the end of x
* @param z The maximum allowed length for z including null terminator
*/
CoreExport int charlcat(char* x,char y,int z);
/** charremove() will remove all instances of a character from a string
* @param mp The string to operate on
* @param remove The character to remove
*/
CoreExport bool charremove(char* mp, char remove);
/** strnewdup() is an implemenetation of strdup() which calls operator new
* rather than malloc to allocate the new string, therefore allowing it to
* be hooked into the C++ memory manager, and freed with operator delete.
* This is required for windows, where we override operators new and delete
* to allow for global allocation between modules and the core.
*/
inline char * strnewdup(const char * s1)
{
size_t len = strlen(s1) + 1;
char * p = new char[len];
memcpy(p, s1, len);
return p;
}
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __IN_INSPSTRING_H +#define __IN_INSPSTRING_H + +#include "inspircd_config.h" +#include <string.h> +#include <cstddef> + +#ifndef HAS_STRLCPY +/** strlcpy() implementation for systems that don't have it (linux) */ +CoreExport size_t strlcpy(char *dst, const char *src, size_t siz); +/** strlcat() implementation for systems that don't have it (linux) */ +CoreExport size_t strlcat(char *dst, const char *src, size_t siz); +#endif + +/** charlcat() will append one character to a string using the same + * safety scemantics as strlcat(). + * @param x The string to operate on + * @param y the character to append to the end of x + * @param z The maximum allowed length for z including null terminator + */ +CoreExport int charlcat(char* x,char y,int z); +/** charremove() will remove all instances of a character from a string + * @param mp The string to operate on + * @param remove The character to remove + */ +CoreExport bool charremove(char* mp, char remove); + +/** strnewdup() is an implemenetation of strdup() which calls operator new + * rather than malloc to allocate the new string, therefore allowing it to + * be hooked into the C++ memory manager, and freed with operator delete. + * This is required for windows, where we override operators new and delete + * to allow for global allocation between modules and the core. + */ +inline char * strnewdup(const char * s1) +{ + size_t len = strlen(s1) + 1; + char * p = new char[len]; + memcpy(p, s1, len); + return p; +} + +#endif + diff --git a/include/mode.h b/include/mode.h index 5f0835523..6d91de1a8 100644 --- a/include/mode.h +++ b/include/mode.h @@ -1 +1,519 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __MODE_H
#define __MODE_H
/* include the common header files */
#include <string>
#include <deque>
#include <vector>
#include "users.h"
#include "channels.h"
#include "ctables.h"
class InspIRCd;
/**
* Holds the values for different type of modes
* that can exist, USER or CHANNEL type.
*/
enum ModeType
{
/** User mode */
MODETYPE_USER = 0,
/** Channel mode */
MODETYPE_CHANNEL = 1
};
/**
* Holds mode actions - modes can be allowed or denied.
*/
enum ModeAction
{
MODEACTION_DENY = 0, /* Drop the mode change, AND a parameter if its a parameterized mode */
MODEACTION_ALLOW = 1 /* Allow the mode */
};
/**
* Used to mask off the mode types in the mode handler
* array. Used in a simple two instruction hashing function
* "(modeletter - 65) OR mask"
*/
enum ModeMasks
{
MASK_USER = 128, /* A user mode */
MASK_CHANNEL = 0 /* A channel mode */
};
/**
* These fixed values can be used to proportionally compare module-defined prefixes to known values.
* For example, if your module queries a chanrec, and is told that user 'joebloggs' has the prefix
* '$', and you dont know what $ means, then you can compare it to these three values to determine
* its worth against them. For example if '$' had a value of 15000, you would know it is of higher
* status than voice, but lower status than halfop.
* No two modes should have equal prefix values.
*/
enum PrefixModeValue
{
/* +v */
VOICE_VALUE = 10000,
/* +h */
HALFOP_VALUE = 20000,
/* +o */
OP_VALUE = 30000
};
/**
* Used by ModeHandler::ModeSet() to return the state of a mode upon a channel or user.
* The pair contains an activity flag, true if the mode is set with the given parameter,
* and the parameter of the mode (or the parameter provided) in the std::string.
*/
typedef std::pair<bool,std::string> ModePair;
/** Each mode is implemented by ONE ModeHandler class.
* You must derive ModeHandler and add the child class to
* the list of modes handled by the ircd, using
* ModeParser::AddMode. When the mode you implement is
* set by a user, the virtual function OnModeChange is
* called. If you specify a value greater than 0 for
* parameters_on or parameters_off, then when the mode is
* set or unset respectively, std::string ¶meter will
* contain the parameter given by the user, else it will
* contain an empty string. You may alter this parameter
* string, and if you alter it to an empty string, and your
* mode is expected to have a parameter, then this is
* equivalent to returning MODEACTION_DENY.
*/
class CoreExport ModeHandler : public Extensible
{
protected:
/**
* Creator/owner pointer
*/
InspIRCd* ServerInstance;
/**
* The mode letter you're implementing.
*/
char mode;
/**
* Number of parameters when being set
*/
int n_params_on;
/**
* Number of parameters when being unset
*/
int n_params_off;
/**
* Mode is a 'list' mode. The behaviour
* of your mode is now set entirely within
* the class as of the 1.1 api, rather than
* inside the mode parser as in the 1.0 api,
* so the only use of this value (along with
* IsListMode()) is for the core to determine
* wether your module can produce 'lists' or not
* (e.g. banlists, etc)
*/
bool list;
/**
* The mode type, either MODETYPE_USER or
* MODETYPE_CHANNEL.
*/
ModeType m_type;
/**
* True if the mode requires oper status
* to set.
*/
bool oper;
/** Mode prefix, or 0
*/
char prefix;
/** Number of items with this mode set on them
*/
unsigned int count;
public:
/**
* The constructor for ModeHandler initalizes the mode handler.
* The constructor of any class you derive from ModeHandler should
* probably call this constructor with the parameters set correctly.
* @param modeletter The mode letter you wish to handle
* @param parameters_on The number of parameters your mode takes when being set. Note that any nonzero value is treated as 1.
* @param parameters_off The number of parameters your mode takes when being unset. Note that any nonzero value is treated as 1.
* @param listmode Set to true if your mode is a listmode, e.g. it will respond to MODE #channel +modechar with a list of items
* @param ModeType Set this to MODETYPE_USER for a usermode, or MODETYPE_CHANNEL for a channelmode.
* @param operonly Set this to true if only opers should be allowed to set or unset the mode.
* @param mprefix For listmodes where parameters are NICKNAMES which are on the channel (for example, +ohv), you may define a prefix.
* When you define a prefix, it can be returned in NAMES, WHO etc if it has the highest value (as returned by GetPrefixRank())
* In the core, the only modes to implement prefixes are +ovh (ops, voice, halfop) which define the prefix characters @, % and +
* and the rank values OP_VALUE, HALFOP_VALUE and VOICE_VALUE respectively. Any prefixes you define should have unique values proportional
* to these three defaults or proportional to another mode in a module you depend on. See src/cmode_o.cpp as an example.
*/
ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix = 0);
/**
* The default destructor does nothing
*/
virtual ~ModeHandler();
/**
* Returns true if the mode is a list mode
*/
bool IsListMode();
/**
* Mode prefix or 0. If this is defined, you should
* also implement GetPrefixRank() to return an integer
* value for this mode prefix.
*/
char GetPrefix();
/** Get number of items with this mode set on them
*/
virtual unsigned int GetCount();
/** Adjust usage count returned by GetCount
*/
virtual void ChangeCount(int modifier);
/**
* Get the 'value' of this modes prefix.
* determines which to display when there are multiple.
* The mode with the highest value is ranked first. See the
* PrefixModeValue enum and chanrec::GetPrefixValue() for
* more information.
*/
virtual unsigned int GetPrefixRank();
/**
* Returns the modes type
*/
ModeType GetModeType();
/**
* Returns true if the mode can only be set/unset by an oper
*/
bool NeedsOper();
/**
* Returns the number of parameters for the mode. Any non-zero
* value should be considered to be equivalent to one.
* @param adding If this is true, the number of parameters required to set the mode should be returned, otherwise the number of parameters required to unset the mode shall be returned.
* @return The number of parameters the mode expects
*/
int GetNumParams(bool adding);
/**
* Returns the mode character this handler handles.
* @return The mode character
*/
char GetModeChar();
/**
* Called when a mode change for your mode occurs.
* @param source Contains the user setting the mode.
* @param dest For usermodes, contains the destination user the mode is being set on. For channelmodes, this is an undefined value.
* @param channel For channel modes, contains the destination channel the modes are being set on. For usermodes, this is an undefined value.
* @param parameter The parameter for your mode, if you indicated that your mode requires a parameter when being set or unset. Note that
* if you alter this value, the new value becomes the one displayed and send out to the network, also, if you set this to an empty string
* but you specified your mode REQUIRES a parameter, this is equivalent to returning MODEACTION_DENY and will prevent the mode from being
* displayed.
* @param adding This value is true when the mode is being set, or false when it is being unset.
* @return MODEACTION_ALLOW to allow the mode, or MODEACTION_DENY to prevent the mode, also see the description of 'parameter'.
*/
virtual ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); /* Can change the mode parameter as its a ref */
/**
* If your mode is a listmode, then this method will be called for displaying an item list, e.g. on MODE #channel +modechar
* without any parameter or other modes in the command.
* @param user The user issuing the command
* @parameter channel The channel they're requesting an item list of (e.g. a banlist, or an exception list etc)
*/
virtual void DisplayList(userrec* user, chanrec* channel);
/**
* If your mode needs special action during a server sync to determine which side wins when comparing timestamps,
* override this function and use it to return true or false. The default implementation just returns true if
* theirs < ours. This will only be called for non-listmodes with parameters, when adding the mode and where
* theirs == ours (therefore the default implementation will always return false).
* @param theirs The timestamp of the remote side
* @param ours The timestamp of the local side
* @param their_param Their parameter if the mode has a parameter
* @param our_param Our parameter if the mode has a parameter
* @param channel The channel we are checking against
* @return True if the other side wins the merge, false if we win the merge for this mode.
*/
virtual bool CheckTimeStamp(time_t theirs, time_t ours, const std::string &their_param, const std::string &our_param, chanrec* channel);
/**
* When a remote server needs to bounce a set of modes, it will call this method for every mode
* in the mode string to determine if the mode is set or not.
* @param source of the mode change, this will be NULL for a server mode
* @param dest Target user of the mode change, if this is a user mode
* @param channel Target channel of the mode change, if this is a channel mode
* @param parameter The parameter given for the mode change, or an empty string
* @returns The first value of the pair should be true if the mode is set with the given parameter.
* In the case of permissions modes such as channelmode +o, this should return true if the user given
* as the parameter has the given privilage on the given channel. The string value of the pair will hold
* the current setting for this mode set locally, when the bool is true, or, the parameter given.
* This allows the local server to enforce our locally set parameters back to a remote server.
*/
virtual ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter);
/**
* When a MODETYPE_USER mode handler is being removed, the server will call this method for every user on the server.
* Your mode handler should remove its user mode from the user by sending the appropriate server modes using
* InspIRCd::SendMode(). The default implementation of this method can remove simple modes which have no parameters,
* and can be used when your mode is of this type, otherwise you must implement a more advanced version of it to remove
* your mode properly from each user.
* @param user The user which the server wants to remove your mode from
*/
virtual void RemoveMode(userrec* user);
/**
* When a MODETYPE_CHANNEL mode handler is being removed, the server will call this method for every channel on the server.
* Your mode handler should remove its user mode from the channel by sending the appropriate server modes using
* InspIRCd::SendMode(). The default implementation of this method can remove simple modes which have no parameters,
* and can be used when your mode is of this type, otherwise you must implement a more advanced version of it to remove
* your mode properly from each channel. Note that in the case of listmodes, you should remove the entire list of items.
* @param channel The channel which the server wants to remove your mode from
*/
virtual void RemoveMode(chanrec* channel);
};
/**
* The ModeWatcher class can be used to alter the behaviour of a mode implemented
* by the core or by another module. To use ModeWatcher, derive a class from it,
* and attach it to the mode using Server::AddModeWatcher and Server::DelModeWatcher.
* A ModeWatcher will be called both before and after the mode change.
*/
class CoreExport ModeWatcher : public Extensible
{
protected:
/**
* Creator/owner pointer
*/
InspIRCd* ServerInstance;
/**
* The mode letter this class is watching
*/
char mode;
/**
* The mode type being watched (user or channel)
*/
ModeType m_type;
public:
/**
* The constructor initializes the mode and the mode type
*/
ModeWatcher(InspIRCd* Instance, char modeletter, ModeType type);
/**
* The default destructor does nothing.
*/
virtual ~ModeWatcher();
/**
* Get the mode character being watched
* @return The mode character being watched
*/
char GetModeChar();
/**
* Get the mode type being watched
* @return The mode type being watched (user or channel)
*/
ModeType GetModeType();
/**
* Before the mode character is processed by its handler, this method will be called.
* @param source The sender of the mode
* @param dest The target user for the mode, if you are watching a user mode
* @param channel The target channel for the mode, if you are watching a channel mode
* @param parameter The parameter of the mode, if the mode is supposed to have a parameter.
* If you alter the parameter you are given, the mode handler will see your atered version
* when it handles the mode.
* @param adding True if the mode is being added and false if it is being removed
* @type The mode type, either MODETYPE_USER or MODETYPE_CHANNEL
* @return True to allow the mode change to go ahead, false to abort it. If you abort the
* change, the mode handler (and ModeWatcher::AfterMode()) will never see the mode change.
*/
virtual bool BeforeMode(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding, ModeType type);
/**
* After the mode character has been processed by the ModeHandler, this method will be called.
* @param source The sender of the mode
* @param dest The target user for the mode, if you are watching a user mode
* @param channel The target channel for the mode, if you are watching a channel mode
* @param parameter The parameter of the mode, if the mode is supposed to have a parameter.
* You cannot alter the parameter here, as the mode handler has already processed it.
* @param adding True if the mode is being added and false if it is being removed
* @type The mode type, either MODETYPE_USER or MODETYPE_CHANNEL
*/
virtual void AfterMode(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter, bool adding, ModeType type);
};
typedef std::vector<ModeWatcher*>::iterator ModeWatchIter;
/** The mode parser handles routing of modes and handling of mode strings.
* It marshalls, controls and maintains both ModeWatcher and ModeHandler classes,
* parses client to server MODE strings for user and channel modes, and performs
* processing for the 004 mode list numeric, amongst other things.
*/
class CoreExport ModeParser : public classbase
{
private:
/**
* Creator/owner pointer
*/
InspIRCd* ServerInstance;
/** Mode handlers for each mode, to access a handler subtract
* 65 from the ascii value of the mode letter.
* The upper bit of the value indicates if its a usermode
* or a channel mode, so we have 256 of them not 64.
*/
ModeHandler* modehandlers[256];
/** Mode watcher classes arranged in the same way as the
* mode handlers, except for instead of having 256 of them
* we have 256 lists of them.
*/
std::vector<ModeWatcher*> modewatchers[256];
/** Displays the current modes of a channel or user.
* Used by ModeParser::Process.
*/
void DisplayCurrentModes(userrec *user, userrec* targetuser, chanrec* targetchannel, const char* text);
/** The string representing the last set of modes to be parsed.
* Use GetLastParse() to get this value, to be used for display purposes.
*/
std::string LastParse;
public:
/** The constructor initializes all the RFC basic modes by using ModeParserAddMode().
*/
ModeParser(InspIRCd* Instance);
/** Used to check if user 'd' should be allowed to do operation 'MASK' on channel 'chan'.
* for example, should 'user A' be able to 'op' on 'channel B'.
*/
userrec* SanityChecks(userrec *user,const char *dest,chanrec *chan,int status);
/** Grant a built in privilage (e.g. ops, halfops, voice) to a user on a channel
*/
const char* Grant(userrec *d,chanrec *chan,int MASK);
/** Revoke a built in privilage (e.g. ops, halfops, voice) to a user on a channel
*/
const char* Revoke(userrec *d,chanrec *chan,int MASK);
/** Tidy a banmask. This makes a banmask 'acceptable' if fields are left out.
* E.g.
*
* nick -> nick!*@*
*
* nick!ident -> nick!ident@*
*
* host.name -> *!*@host.name
*
* ident@host.name -> *!ident@host.name
*
* This method can be used on both IPV4 and IPV6 user masks.
*/
static void CleanMask(std::string &mask);
/** Get the last string to be processed, as it was sent to the user or channel.
* Use this to display a string you just sent to be parsed, as the actual output
* may be different to what you sent after it has been 'cleaned up' by the parser.
* @return Last parsed string, as seen by users.
*/
const std::string& GetLastParse();
/** Add a mode to the mode parser. The modeletter parameter
* is purely to save on doing a lookup in the function, as
* strictly it could be obtained via ModeHandler::GetModeChar().
* @return True if the mode was successfully added.
*/
bool AddMode(ModeHandler* mh, unsigned const char modeletter);
/** Delete a mode from the mode parser.
* When a mode is deleted, the mode handler will be called
* for every user (if it is a user mode) or for every channel
* (if it is a channel mode) to unset the mode on all objects.
* This prevents modes staying in the system which no longer exist.
* @param mh The mode handler to remove
* @return True if the mode was successfully removed.
*/
bool DelMode(ModeHandler* mh);
/** Add a mode watcher.
* A mode watcher is triggered before and after a mode handler is
* triggered. See the documentation of class ModeWatcher for more
* information.
* @param mw The ModeWatcher you want to add
* @return True if the ModeWatcher was added correctly
*/
bool AddModeWatcher(ModeWatcher* mw);
/** Delete a mode watcher.
* A mode watcher is triggered before and after a mode handler is
* triggered. See the documentation of class ModeWatcher for more
* information.
* @param mw The ModeWatcher you want to delete
* @return True if the ModeWatcher was deleted correctly
*/
bool DelModeWatcher(ModeWatcher* mw);
/** Process a set of mode changes from a server or user.
* @param parameters The parameters of the mode change, in the format
* they would be from a MODE command.
* @param pcnt The number of items in the parameters array
* @param user The user setting or removing the modes. When the modes are set
* by a server, an 'uninitialized' userrec is used, where *user::nick == NULL
* and *user->server == NULL.
* @param servermode True if a server is setting the mode.
*/
void Process(const char** parameters, int pcnt, userrec *user, bool servermode);
/** Find the mode handler for a given mode and type.
* @param modeletter mode letter to search for
* @param type of mode to search for, user or channel
* @returns a pointer to a ModeHandler class, or NULL of there isnt a handler for the given mode
*/
ModeHandler* FindMode(unsigned const char modeletter, ModeType mt);
/** Find a mode handler by its prefix.
* If there is no mode handler with the given prefix, NULL will be returned.
* @param pfxletter The prefix to find, e.g. '@'
* @return The mode handler which handles this prefix, or NULL if there is none.
*/
ModeHandler* FindPrefix(unsigned const char pfxletter);
/** Returns a list of mode characters which are usermodes.
* This is used in the 004 numeric when users connect.
*/
std::string UserModeList();
/** Returns a list of channel mode characters which are listmodes.
* This is used in the 004 numeric when users connect.
*/
std::string ChannelModeList();
/** Returns a list of channel mode characters which take parameters.
* This is used in the 004 numeric when users connect.
*/
std::string ParaModeList();
/** Generates the CHANMODES= 005 sequence
*/
std::string ChanModes();
/** Used by this class internally during std::sort and 005 generation
*/
static bool PrefixComparison(prefixtype one, prefixtype two);
/** This returns the PREFIX=(ohv)@%+ section of the 005 numeric.
*/
std::string BuildPrefixes();
/** This returns the privilages of a user upon a channel, in the format of a mode change.
* For example, if a user has privilages +avh, this will return the string "avh nick nick nick".
* This is used by the core when cycling a user to refresh their hostname. You may use it for
* similar purposes.
* @param user The username to look up
* @param channel The channel name to look up the privilages of the user for
* @return The mode string.
*/
std::string ModeString(userrec* user, chanrec* channel);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __MODE_H +#define __MODE_H + +/* include the common header files */ +#include <string> +#include <deque> +#include <vector> +#include "users.h" +#include "channels.h" +#include "ctables.h" + +class InspIRCd; + +/** + * Holds the values for different type of modes + * that can exist, USER or CHANNEL type. + */ +enum ModeType +{ + /** User mode */ + MODETYPE_USER = 0, + /** Channel mode */ + MODETYPE_CHANNEL = 1 +}; + +/** + * Holds mode actions - modes can be allowed or denied. + */ +enum ModeAction +{ + MODEACTION_DENY = 0, /* Drop the mode change, AND a parameter if its a parameterized mode */ + MODEACTION_ALLOW = 1 /* Allow the mode */ +}; + +/** + * Used to mask off the mode types in the mode handler + * array. Used in a simple two instruction hashing function + * "(modeletter - 65) OR mask" + */ +enum ModeMasks +{ + MASK_USER = 128, /* A user mode */ + MASK_CHANNEL = 0 /* A channel mode */ +}; + +/** + * These fixed values can be used to proportionally compare module-defined prefixes to known values. + * For example, if your module queries a chanrec, and is told that user 'joebloggs' has the prefix + * '$', and you dont know what $ means, then you can compare it to these three values to determine + * its worth against them. For example if '$' had a value of 15000, you would know it is of higher + * status than voice, but lower status than halfop. + * No two modes should have equal prefix values. + */ +enum PrefixModeValue +{ + /* +v */ + VOICE_VALUE = 10000, + /* +h */ + HALFOP_VALUE = 20000, + /* +o */ + OP_VALUE = 30000 +}; + +/** + * Used by ModeHandler::ModeSet() to return the state of a mode upon a channel or user. + * The pair contains an activity flag, true if the mode is set with the given parameter, + * and the parameter of the mode (or the parameter provided) in the std::string. + */ +typedef std::pair<bool,std::string> ModePair; + +/** Each mode is implemented by ONE ModeHandler class. + * You must derive ModeHandler and add the child class to + * the list of modes handled by the ircd, using + * ModeParser::AddMode. When the mode you implement is + * set by a user, the virtual function OnModeChange is + * called. If you specify a value greater than 0 for + * parameters_on or parameters_off, then when the mode is + * set or unset respectively, std::string ¶meter will + * contain the parameter given by the user, else it will + * contain an empty string. You may alter this parameter + * string, and if you alter it to an empty string, and your + * mode is expected to have a parameter, then this is + * equivalent to returning MODEACTION_DENY. + */ +class CoreExport ModeHandler : public Extensible +{ + protected: + /** + * Creator/owner pointer + */ + InspIRCd* ServerInstance; + /** + * The mode letter you're implementing. + */ + char mode; + /** + * Number of parameters when being set + */ + int n_params_on; + /** + * Number of parameters when being unset + */ + int n_params_off; + /** + * Mode is a 'list' mode. The behaviour + * of your mode is now set entirely within + * the class as of the 1.1 api, rather than + * inside the mode parser as in the 1.0 api, + * so the only use of this value (along with + * IsListMode()) is for the core to determine + * wether your module can produce 'lists' or not + * (e.g. banlists, etc) + */ + bool list; + /** + * The mode type, either MODETYPE_USER or + * MODETYPE_CHANNEL. + */ + ModeType m_type; + /** + * True if the mode requires oper status + * to set. + */ + bool oper; + + /** Mode prefix, or 0 + */ + char prefix; + + /** Number of items with this mode set on them + */ + unsigned int count; + + public: + /** + * The constructor for ModeHandler initalizes the mode handler. + * The constructor of any class you derive from ModeHandler should + * probably call this constructor with the parameters set correctly. + * @param modeletter The mode letter you wish to handle + * @param parameters_on The number of parameters your mode takes when being set. Note that any nonzero value is treated as 1. + * @param parameters_off The number of parameters your mode takes when being unset. Note that any nonzero value is treated as 1. + * @param listmode Set to true if your mode is a listmode, e.g. it will respond to MODE #channel +modechar with a list of items + * @param ModeType Set this to MODETYPE_USER for a usermode, or MODETYPE_CHANNEL for a channelmode. + * @param operonly Set this to true if only opers should be allowed to set or unset the mode. + * @param mprefix For listmodes where parameters are NICKNAMES which are on the channel (for example, +ohv), you may define a prefix. + * When you define a prefix, it can be returned in NAMES, WHO etc if it has the highest value (as returned by GetPrefixRank()) + * In the core, the only modes to implement prefixes are +ovh (ops, voice, halfop) which define the prefix characters @, % and + + * and the rank values OP_VALUE, HALFOP_VALUE and VOICE_VALUE respectively. Any prefixes you define should have unique values proportional + * to these three defaults or proportional to another mode in a module you depend on. See src/cmode_o.cpp as an example. + */ + ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix = 0); + /** + * The default destructor does nothing + */ + virtual ~ModeHandler(); + /** + * Returns true if the mode is a list mode + */ + bool IsListMode(); + /** + * Mode prefix or 0. If this is defined, you should + * also implement GetPrefixRank() to return an integer + * value for this mode prefix. + */ + char GetPrefix(); + /** Get number of items with this mode set on them + */ + virtual unsigned int GetCount(); + /** Adjust usage count returned by GetCount + */ + virtual void ChangeCount(int modifier); + /** + * Get the 'value' of this modes prefix. + * determines which to display when there are multiple. + * The mode with the highest value is ranked first. See the + * PrefixModeValue enum and chanrec::GetPrefixValue() for + * more information. + */ + virtual unsigned int GetPrefixRank(); + /** + * Returns the modes type + */ + ModeType GetModeType(); + /** + * Returns true if the mode can only be set/unset by an oper + */ + bool NeedsOper(); + /** + * Returns the number of parameters for the mode. Any non-zero + * value should be considered to be equivalent to one. + * @param adding If this is true, the number of parameters required to set the mode should be returned, otherwise the number of parameters required to unset the mode shall be returned. + * @return The number of parameters the mode expects + */ + int GetNumParams(bool adding); + /** + * Returns the mode character this handler handles. + * @return The mode character + */ + char GetModeChar(); + + /** + * Called when a mode change for your mode occurs. + * @param source Contains the user setting the mode. + * @param dest For usermodes, contains the destination user the mode is being set on. For channelmodes, this is an undefined value. + * @param channel For channel modes, contains the destination channel the modes are being set on. For usermodes, this is an undefined value. + * @param parameter The parameter for your mode, if you indicated that your mode requires a parameter when being set or unset. Note that + * if you alter this value, the new value becomes the one displayed and send out to the network, also, if you set this to an empty string + * but you specified your mode REQUIRES a parameter, this is equivalent to returning MODEACTION_DENY and will prevent the mode from being + * displayed. + * @param adding This value is true when the mode is being set, or false when it is being unset. + * @return MODEACTION_ALLOW to allow the mode, or MODEACTION_DENY to prevent the mode, also see the description of 'parameter'. + */ + virtual ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); /* Can change the mode parameter as its a ref */ + /** + * If your mode is a listmode, then this method will be called for displaying an item list, e.g. on MODE #channel +modechar + * without any parameter or other modes in the command. + * @param user The user issuing the command + * @parameter channel The channel they're requesting an item list of (e.g. a banlist, or an exception list etc) + */ + virtual void DisplayList(userrec* user, chanrec* channel); + /** + * If your mode needs special action during a server sync to determine which side wins when comparing timestamps, + * override this function and use it to return true or false. The default implementation just returns true if + * theirs < ours. This will only be called for non-listmodes with parameters, when adding the mode and where + * theirs == ours (therefore the default implementation will always return false). + * @param theirs The timestamp of the remote side + * @param ours The timestamp of the local side + * @param their_param Their parameter if the mode has a parameter + * @param our_param Our parameter if the mode has a parameter + * @param channel The channel we are checking against + * @return True if the other side wins the merge, false if we win the merge for this mode. + */ + virtual bool CheckTimeStamp(time_t theirs, time_t ours, const std::string &their_param, const std::string &our_param, chanrec* channel); + + /** + * When a remote server needs to bounce a set of modes, it will call this method for every mode + * in the mode string to determine if the mode is set or not. + * @param source of the mode change, this will be NULL for a server mode + * @param dest Target user of the mode change, if this is a user mode + * @param channel Target channel of the mode change, if this is a channel mode + * @param parameter The parameter given for the mode change, or an empty string + * @returns The first value of the pair should be true if the mode is set with the given parameter. + * In the case of permissions modes such as channelmode +o, this should return true if the user given + * as the parameter has the given privilage on the given channel. The string value of the pair will hold + * the current setting for this mode set locally, when the bool is true, or, the parameter given. + * This allows the local server to enforce our locally set parameters back to a remote server. + */ + virtual ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter); + + /** + * When a MODETYPE_USER mode handler is being removed, the server will call this method for every user on the server. + * Your mode handler should remove its user mode from the user by sending the appropriate server modes using + * InspIRCd::SendMode(). The default implementation of this method can remove simple modes which have no parameters, + * and can be used when your mode is of this type, otherwise you must implement a more advanced version of it to remove + * your mode properly from each user. + * @param user The user which the server wants to remove your mode from + */ + virtual void RemoveMode(userrec* user); + + /** + * When a MODETYPE_CHANNEL mode handler is being removed, the server will call this method for every channel on the server. + * Your mode handler should remove its user mode from the channel by sending the appropriate server modes using + * InspIRCd::SendMode(). The default implementation of this method can remove simple modes which have no parameters, + * and can be used when your mode is of this type, otherwise you must implement a more advanced version of it to remove + * your mode properly from each channel. Note that in the case of listmodes, you should remove the entire list of items. + * @param channel The channel which the server wants to remove your mode from + */ + virtual void RemoveMode(chanrec* channel); +}; + +/** + * The ModeWatcher class can be used to alter the behaviour of a mode implemented + * by the core or by another module. To use ModeWatcher, derive a class from it, + * and attach it to the mode using Server::AddModeWatcher and Server::DelModeWatcher. + * A ModeWatcher will be called both before and after the mode change. + */ +class CoreExport ModeWatcher : public Extensible +{ + protected: + /** + * Creator/owner pointer + */ + InspIRCd* ServerInstance; + /** + * The mode letter this class is watching + */ + char mode; + /** + * The mode type being watched (user or channel) + */ + ModeType m_type; + + public: + /** + * The constructor initializes the mode and the mode type + */ + ModeWatcher(InspIRCd* Instance, char modeletter, ModeType type); + /** + * The default destructor does nothing. + */ + virtual ~ModeWatcher(); + + /** + * Get the mode character being watched + * @return The mode character being watched + */ + char GetModeChar(); + /** + * Get the mode type being watched + * @return The mode type being watched (user or channel) + */ + ModeType GetModeType(); + + /** + * Before the mode character is processed by its handler, this method will be called. + * @param source The sender of the mode + * @param dest The target user for the mode, if you are watching a user mode + * @param channel The target channel for the mode, if you are watching a channel mode + * @param parameter The parameter of the mode, if the mode is supposed to have a parameter. + * If you alter the parameter you are given, the mode handler will see your atered version + * when it handles the mode. + * @param adding True if the mode is being added and false if it is being removed + * @type The mode type, either MODETYPE_USER or MODETYPE_CHANNEL + * @return True to allow the mode change to go ahead, false to abort it. If you abort the + * change, the mode handler (and ModeWatcher::AfterMode()) will never see the mode change. + */ + virtual bool BeforeMode(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding, ModeType type); + /** + * After the mode character has been processed by the ModeHandler, this method will be called. + * @param source The sender of the mode + * @param dest The target user for the mode, if you are watching a user mode + * @param channel The target channel for the mode, if you are watching a channel mode + * @param parameter The parameter of the mode, if the mode is supposed to have a parameter. + * You cannot alter the parameter here, as the mode handler has already processed it. + * @param adding True if the mode is being added and false if it is being removed + * @type The mode type, either MODETYPE_USER or MODETYPE_CHANNEL + */ + virtual void AfterMode(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter, bool adding, ModeType type); +}; + +typedef std::vector<ModeWatcher*>::iterator ModeWatchIter; + +/** The mode parser handles routing of modes and handling of mode strings. + * It marshalls, controls and maintains both ModeWatcher and ModeHandler classes, + * parses client to server MODE strings for user and channel modes, and performs + * processing for the 004 mode list numeric, amongst other things. + */ +class CoreExport ModeParser : public classbase +{ + private: + /** + * Creator/owner pointer + */ + InspIRCd* ServerInstance; + /** Mode handlers for each mode, to access a handler subtract + * 65 from the ascii value of the mode letter. + * The upper bit of the value indicates if its a usermode + * or a channel mode, so we have 256 of them not 64. + */ + ModeHandler* modehandlers[256]; + /** Mode watcher classes arranged in the same way as the + * mode handlers, except for instead of having 256 of them + * we have 256 lists of them. + */ + std::vector<ModeWatcher*> modewatchers[256]; + /** Displays the current modes of a channel or user. + * Used by ModeParser::Process. + */ + void DisplayCurrentModes(userrec *user, userrec* targetuser, chanrec* targetchannel, const char* text); + + /** The string representing the last set of modes to be parsed. + * Use GetLastParse() to get this value, to be used for display purposes. + */ + std::string LastParse; + + public: + + /** The constructor initializes all the RFC basic modes by using ModeParserAddMode(). + */ + ModeParser(InspIRCd* Instance); + + /** Used to check if user 'd' should be allowed to do operation 'MASK' on channel 'chan'. + * for example, should 'user A' be able to 'op' on 'channel B'. + */ + userrec* SanityChecks(userrec *user,const char *dest,chanrec *chan,int status); + /** Grant a built in privilage (e.g. ops, halfops, voice) to a user on a channel + */ + const char* Grant(userrec *d,chanrec *chan,int MASK); + /** Revoke a built in privilage (e.g. ops, halfops, voice) to a user on a channel + */ + const char* Revoke(userrec *d,chanrec *chan,int MASK); + /** Tidy a banmask. This makes a banmask 'acceptable' if fields are left out. + * E.g. + * + * nick -> nick!*@* + * + * nick!ident -> nick!ident@* + * + * host.name -> *!*@host.name + * + * ident@host.name -> *!ident@host.name + * + * This method can be used on both IPV4 and IPV6 user masks. + */ + static void CleanMask(std::string &mask); + /** Get the last string to be processed, as it was sent to the user or channel. + * Use this to display a string you just sent to be parsed, as the actual output + * may be different to what you sent after it has been 'cleaned up' by the parser. + * @return Last parsed string, as seen by users. + */ + const std::string& GetLastParse(); + /** Add a mode to the mode parser. The modeletter parameter + * is purely to save on doing a lookup in the function, as + * strictly it could be obtained via ModeHandler::GetModeChar(). + * @return True if the mode was successfully added. + */ + bool AddMode(ModeHandler* mh, unsigned const char modeletter); + /** Delete a mode from the mode parser. + * When a mode is deleted, the mode handler will be called + * for every user (if it is a user mode) or for every channel + * (if it is a channel mode) to unset the mode on all objects. + * This prevents modes staying in the system which no longer exist. + * @param mh The mode handler to remove + * @return True if the mode was successfully removed. + */ + bool DelMode(ModeHandler* mh); + /** Add a mode watcher. + * A mode watcher is triggered before and after a mode handler is + * triggered. See the documentation of class ModeWatcher for more + * information. + * @param mw The ModeWatcher you want to add + * @return True if the ModeWatcher was added correctly + */ + bool AddModeWatcher(ModeWatcher* mw); + /** Delete a mode watcher. + * A mode watcher is triggered before and after a mode handler is + * triggered. See the documentation of class ModeWatcher for more + * information. + * @param mw The ModeWatcher you want to delete + * @return True if the ModeWatcher was deleted correctly + */ + bool DelModeWatcher(ModeWatcher* mw); + /** Process a set of mode changes from a server or user. + * @param parameters The parameters of the mode change, in the format + * they would be from a MODE command. + * @param pcnt The number of items in the parameters array + * @param user The user setting or removing the modes. When the modes are set + * by a server, an 'uninitialized' userrec is used, where *user::nick == NULL + * and *user->server == NULL. + * @param servermode True if a server is setting the mode. + */ + void Process(const char** parameters, int pcnt, userrec *user, bool servermode); + + /** Find the mode handler for a given mode and type. + * @param modeletter mode letter to search for + * @param type of mode to search for, user or channel + * @returns a pointer to a ModeHandler class, or NULL of there isnt a handler for the given mode + */ + ModeHandler* FindMode(unsigned const char modeletter, ModeType mt); + + /** Find a mode handler by its prefix. + * If there is no mode handler with the given prefix, NULL will be returned. + * @param pfxletter The prefix to find, e.g. '@' + * @return The mode handler which handles this prefix, or NULL if there is none. + */ + ModeHandler* FindPrefix(unsigned const char pfxletter); + + /** Returns a list of mode characters which are usermodes. + * This is used in the 004 numeric when users connect. + */ + std::string UserModeList(); + + /** Returns a list of channel mode characters which are listmodes. + * This is used in the 004 numeric when users connect. + */ + std::string ChannelModeList(); + + /** Returns a list of channel mode characters which take parameters. + * This is used in the 004 numeric when users connect. + */ + std::string ParaModeList(); + + /** Generates the CHANMODES= 005 sequence + */ + std::string ChanModes(); + /** Used by this class internally during std::sort and 005 generation + */ + static bool PrefixComparison(prefixtype one, prefixtype two); + + /** This returns the PREFIX=(ohv)@%+ section of the 005 numeric. + */ + std::string BuildPrefixes(); + + /** This returns the privilages of a user upon a channel, in the format of a mode change. + * For example, if a user has privilages +avh, this will return the string "avh nick nick nick". + * This is used by the core when cycling a user to refresh their hostname. You may use it for + * similar purposes. + * @param user The username to look up + * @param channel The channel name to look up the privilages of the user for + * @return The mode string. + */ + std::string ModeString(userrec* user, chanrec* channel); +}; + +#endif + diff --git a/include/modes/cmode_b.h b/include/modes/cmode_b.h index b9e403258..2fe3de614 100644 --- a/include/modes/cmode_b.h +++ b/include/modes/cmode_b.h @@ -1 +1,35 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
#include "channels.h"
class InspIRCd;
/** Channel mode +b
*/
class ModeChannelBan : public ModeHandler
{
private:
BanItem b;
public:
ModeChannelBan(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
std::string& AddBan(userrec *user,std::string& dest,chanrec *chan,int status);
std::string& DelBan(userrec *user,std::string& dest,chanrec *chan,int status);
void DisplayList(userrec* user, chanrec* channel);
ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter);
void RemoveMode(userrec* user);
void RemoveMode(chanrec* channel);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" +#include "channels.h" + +class InspIRCd; + +/** Channel mode +b + */ +class ModeChannelBan : public ModeHandler +{ + private: + BanItem b; + public: + ModeChannelBan(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); + std::string& AddBan(userrec *user,std::string& dest,chanrec *chan,int status); + std::string& DelBan(userrec *user,std::string& dest,chanrec *chan,int status); + void DisplayList(userrec* user, chanrec* channel); + ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter); + void RemoveMode(userrec* user); + void RemoveMode(chanrec* channel); +}; + diff --git a/include/modes/cmode_h.h b/include/modes/cmode_h.h index 9792fcb00..77d1d57ae 100644 --- a/include/modes/cmode_h.h +++ b/include/modes/cmode_h.h @@ -1 +1,34 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
#include "channels.h"
class InspIRCd;
/** Channel mode +h
*/
class ModeChannelHalfOp : public ModeHandler
{
private:
public:
ModeChannelHalfOp(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
std::string AddHalfOp(userrec *user,const char *dest,chanrec *chan,int status);
std::string DelHalfOp(userrec *user,const char *dest,chanrec *chan,int status);
ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter);
unsigned int GetPrefixRank();
void RemoveMode(chanrec* channel);
void RemoveMode(userrec* user);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" +#include "channels.h" + +class InspIRCd; + +/** Channel mode +h + */ +class ModeChannelHalfOp : public ModeHandler +{ + private: + public: + ModeChannelHalfOp(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); + std::string AddHalfOp(userrec *user,const char *dest,chanrec *chan,int status); + std::string DelHalfOp(userrec *user,const char *dest,chanrec *chan,int status); + ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter); + unsigned int GetPrefixRank(); + void RemoveMode(chanrec* channel); + void RemoveMode(userrec* user); +}; + diff --git a/include/modes/cmode_i.h b/include/modes/cmode_i.h index 9df5314aa..fb177dc0f 100644 --- a/include/modes/cmode_i.h +++ b/include/modes/cmode_i.h @@ -1 +1,25 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** Channel mode +i
*/
class ModeChannelInviteOnly : public ModeHandler
{
public:
ModeChannelInviteOnly(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** Channel mode +i + */ +class ModeChannelInviteOnly : public ModeHandler +{ + public: + ModeChannelInviteOnly(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); +}; diff --git a/include/modes/cmode_k.h b/include/modes/cmode_k.h index 695518bf9..51e8ffcaa 100644 --- a/include/modes/cmode_k.h +++ b/include/modes/cmode_k.h @@ -1 +1,29 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** Channel mode +k
*/
class ModeChannelKey : public ModeHandler
{
public:
ModeChannelKey(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter);
bool CheckTimeStamp(time_t theirs, time_t ours, const std::string &their_param, const std::string &our_param, chanrec* channel);
void RemoveMode(chanrec* channel);
void RemoveMode(userrec* user);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** Channel mode +k + */ +class ModeChannelKey : public ModeHandler +{ + public: + ModeChannelKey(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); + ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter); + bool CheckTimeStamp(time_t theirs, time_t ours, const std::string &their_param, const std::string &our_param, chanrec* channel); + void RemoveMode(chanrec* channel); + void RemoveMode(userrec* user); +}; diff --git a/include/modes/cmode_l.h b/include/modes/cmode_l.h index 49228479f..63b4a1ef1 100644 --- a/include/modes/cmode_l.h +++ b/include/modes/cmode_l.h @@ -1 +1,27 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** Channel mode +l
*/
class ModeChannelLimit : public ModeHandler
{
public:
ModeChannelLimit(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter);
bool CheckTimeStamp(time_t theirs, time_t ours, const std::string &their_param, const std::string &our_param, chanrec* channel);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** Channel mode +l + */ +class ModeChannelLimit : public ModeHandler +{ + public: + ModeChannelLimit(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); + ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter); + bool CheckTimeStamp(time_t theirs, time_t ours, const std::string &their_param, const std::string &our_param, chanrec* channel); +}; diff --git a/include/modes/cmode_m.h b/include/modes/cmode_m.h index 885b0321e..52288de4c 100644 --- a/include/modes/cmode_m.h +++ b/include/modes/cmode_m.h @@ -1 +1,25 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** Channel mode +m
*/
class ModeChannelModerated : public ModeHandler
{
public:
ModeChannelModerated(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** Channel mode +m + */ +class ModeChannelModerated : public ModeHandler +{ + public: + ModeChannelModerated(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); +}; diff --git a/include/modes/cmode_n.h b/include/modes/cmode_n.h index dcc0edccb..953e0d671 100644 --- a/include/modes/cmode_n.h +++ b/include/modes/cmode_n.h @@ -1 +1,25 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** Channel mode +n
*/
class ModeChannelNoExternal : public ModeHandler
{
public:
ModeChannelNoExternal(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** Channel mode +n + */ +class ModeChannelNoExternal : public ModeHandler +{ + public: + ModeChannelNoExternal(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); +}; diff --git a/include/modes/cmode_o.h b/include/modes/cmode_o.h index 4198a3f20..c86fb4586 100644 --- a/include/modes/cmode_o.h +++ b/include/modes/cmode_o.h @@ -1 +1,34 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
#include "channels.h"
class InspIRCd;
/** Channel mode +o
*/
class ModeChannelOp : public ModeHandler
{
private:
public:
ModeChannelOp(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
std::string AddOp(userrec *user,const char *dest,chanrec *chan,int status);
std::string DelOp(userrec *user,const char *dest,chanrec *chan,int status);
ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter);
unsigned int GetPrefixRank();
void RemoveMode(chanrec* channel);
void RemoveMode(userrec* user);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" +#include "channels.h" + +class InspIRCd; + +/** Channel mode +o + */ +class ModeChannelOp : public ModeHandler +{ + private: + public: + ModeChannelOp(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); + std::string AddOp(userrec *user,const char *dest,chanrec *chan,int status); + std::string DelOp(userrec *user,const char *dest,chanrec *chan,int status); + ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter); + unsigned int GetPrefixRank(); + void RemoveMode(chanrec* channel); + void RemoveMode(userrec* user); +}; + diff --git a/include/modes/cmode_p.h b/include/modes/cmode_p.h index 123827ea7..ad3f3ae89 100644 --- a/include/modes/cmode_p.h +++ b/include/modes/cmode_p.h @@ -1 +1,25 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** Channel mode +p
*/
class ModeChannelPrivate : public ModeHandler
{
public:
ModeChannelPrivate(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** Channel mode +p + */ +class ModeChannelPrivate : public ModeHandler +{ + public: + ModeChannelPrivate(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); +}; diff --git a/include/modes/cmode_s.h b/include/modes/cmode_s.h index 383e5c083..0bc229c37 100644 --- a/include/modes/cmode_s.h +++ b/include/modes/cmode_s.h @@ -1 +1,25 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** Channel mode +s
*/
class ModeChannelSecret : public ModeHandler
{
public:
ModeChannelSecret(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** Channel mode +s + */ +class ModeChannelSecret : public ModeHandler +{ + public: + ModeChannelSecret(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); +}; diff --git a/include/modes/cmode_t.h b/include/modes/cmode_t.h index 4ddd51730..8a7517ee3 100644 --- a/include/modes/cmode_t.h +++ b/include/modes/cmode_t.h @@ -1 +1,25 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** Channel mode +t
*/
class ModeChannelTopicOps : public ModeHandler
{
public:
ModeChannelTopicOps(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** Channel mode +t + */ +class ModeChannelTopicOps : public ModeHandler +{ + public: + ModeChannelTopicOps(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); +}; diff --git a/include/modes/cmode_v.h b/include/modes/cmode_v.h index a1d40ddc4..75420a6d5 100644 --- a/include/modes/cmode_v.h +++ b/include/modes/cmode_v.h @@ -1 +1,34 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
#include "channels.h"
class InspIRCd;
/** Channel mode +v
*/
class ModeChannelVoice : public ModeHandler
{
private:
public:
ModeChannelVoice(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
std::string AddVoice(userrec *user,const char *dest,chanrec *chan,int status);
std::string DelVoice(userrec *user,const char *dest,chanrec *chan,int status);
ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter);
unsigned int GetPrefixRank();
void RemoveMode(userrec* user);
void RemoveMode(chanrec* channel);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" +#include "channels.h" + +class InspIRCd; + +/** Channel mode +v + */ +class ModeChannelVoice : public ModeHandler +{ + private: + public: + ModeChannelVoice(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); + std::string AddVoice(userrec *user,const char *dest,chanrec *chan,int status); + std::string DelVoice(userrec *user,const char *dest,chanrec *chan,int status); + ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter); + unsigned int GetPrefixRank(); + void RemoveMode(userrec* user); + void RemoveMode(chanrec* channel); +}; + diff --git a/include/modes/umode_i.h b/include/modes/umode_i.h index 4319ac0a5..cc7d15102 100644 --- a/include/modes/umode_i.h +++ b/include/modes/umode_i.h @@ -1 +1,26 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** User mode +i
*/
class ModeUserInvisible : public ModeHandler
{
public:
ModeUserInvisible(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
unsigned int GetCount();
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** User mode +i + */ +class ModeUserInvisible : public ModeHandler +{ + public: + ModeUserInvisible(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); + unsigned int GetCount(); +}; diff --git a/include/modes/umode_n.h b/include/modes/umode_n.h index 9a944d41c..cd1275acc 100644 --- a/include/modes/umode_n.h +++ b/include/modes/umode_n.h @@ -1 +1,25 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** User mode +n
*/
class ModeUserServerNoticeMask : public ModeHandler
{
public:
ModeUserServerNoticeMask(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** User mode +n + */ +class ModeUserServerNoticeMask : public ModeHandler +{ + public: + ModeUserServerNoticeMask(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); +}; diff --git a/include/modes/umode_o.h b/include/modes/umode_o.h index 7548a087a..7dfdb4128 100644 --- a/include/modes/umode_o.h +++ b/include/modes/umode_o.h @@ -1 +1,26 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** User mode +o
*/
class ModeUserOperator : public ModeHandler
{
public:
ModeUserOperator(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
unsigned int GetCount();
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** User mode +o + */ +class ModeUserOperator : public ModeHandler +{ + public: + ModeUserOperator(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); + unsigned int GetCount(); +}; diff --git a/include/modes/umode_s.h b/include/modes/umode_s.h index 98264298b..cda223eee 100644 --- a/include/modes/umode_s.h +++ b/include/modes/umode_s.h @@ -1 +1,26 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** User mode +s
*/
class ModeUserServerNotice : public ModeHandler
{
public:
ModeUserServerNotice(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
unsigned int GetCount();
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** User mode +s + */ +class ModeUserServerNotice : public ModeHandler +{ + public: + ModeUserServerNotice(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); + unsigned int GetCount(); +}; diff --git a/include/modes/umode_w.h b/include/modes/umode_w.h index 26e214460..271e959c4 100644 --- a/include/modes/umode_w.h +++ b/include/modes/umode_w.h @@ -1 +1,26 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "mode.h"
class InspIRCd;
/** User mode +w
*/
class ModeUserWallops : public ModeHandler
{
public:
ModeUserWallops(InspIRCd* Instance);
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding);
unsigned int GetCount();
};
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "mode.h" + +class InspIRCd; + +/** User mode +w + */ +class ModeUserWallops : public ModeHandler +{ + public: + ModeUserWallops(InspIRCd* Instance); + ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding); + unsigned int GetCount(); +}; diff --git a/include/modules.h b/include/modules.h index 51d117b17..389fa6184 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1 +1,1696 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __MODULES_H
#define __MODULES_H
/** Used with OnAccessCheck() method of modules
*/
enum AccessControlType {
ACR_DEFAULT, // Do default action (act as if the module isnt even loaded)
ACR_DENY, // deny the action
ACR_ALLOW, // allow the action
AC_KICK, // a user is being kicked
AC_DEOP, // a user is being deopped
AC_OP, // a user is being opped
AC_VOICE, // a user is being voiced
AC_DEVOICE, // a user is being devoiced
AC_HALFOP, // a user is being halfopped
AC_DEHALFOP, // a user is being dehalfopped
AC_INVITE, // a user is being invited
AC_GENERAL_MODE // a channel mode is being changed
};
/** Used to define a set of behavior bits for a module
*/
enum ModuleFlags {
VF_STATIC = 1, // module is static, cannot be /unloadmodule'd
VF_VENDOR = 2, // module is a vendor module (came in the original tarball, not 3rd party)
VF_SERVICEPROVIDER = 4, // module provides a service to other modules (can be a dependency)
VF_COMMON = 8 // module needs to be common on all servers in a network to link
};
/** Used with SendToMode()
*/
enum WriteModeFlags {
WM_AND = 1,
WM_OR = 2
};
/** Used to represent an event type, for user, channel or server
*/
enum TargetTypeFlags {
TYPE_USER = 1,
TYPE_CHANNEL,
TYPE_SERVER,
TYPE_OTHER
};
/** Used to represent wether a message was PRIVMSG or NOTICE
*/
enum MessageType {
MSG_PRIVMSG = 0,
MSG_NOTICE = 1
};
#include "globals.h"
#include "dynamic.h"
#include "base.h"
#include "ctables.h"
#include "inspsocket.h"
#include <string>
#include <deque>
#include <sstream>
#include "timer.h"
#include "mode.h"
#include "dns.h"
/** 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 11025
#ifdef IPV6
#define API_VERSION (NATIVE_API_VERSION * 10)
#else
#define API_VERSION (NATIVE_API_VERSION * 1)
#endif
class ServerConfig;
/* Forward-delacare module for ModuleMessage etc
*/
class Module;
/** Low level definition of a FileReader classes file cache area -
* a text file seperated into lines.
*/
typedef std::deque<std::string> file_cache;
/** A set of strings.
*/
typedef file_cache string_list;
/** Holds a list of 'published features' for modules.
*/
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.:
* 'FOREACH_MOD(I_OnConnect,OnConnect(user));'
*/
#define FOREACH_MOD(y,x) if (ServerInstance->Config->global_implementation[y] > 0) { \
for (int _i = 0; _i <= ServerInstance->GetModuleCount(); _i++) { \
if (ServerInstance->Config->implement_lists[_i][y]) \
try \
{ \
ServerInstance->modules[_i]->x ; \
} \
catch (CoreException& modexcept) \
{ \
ServerInstance->Log(DEFAULT,"Exception cought: %s",modexcept.GetReason()); \
} \
} \
}
/**
* This #define allows us to call a method in all
* loaded modules in a readable simple way and pass
* an instance pointer to the macro. e.g.:
* 'FOREACH_MOD_I(Instance, OnConnect, OnConnect(user));'
*/
#define FOREACH_MOD_I(z,y,x) if (z->Config->global_implementation[y] > 0) { \
for (int _i = 0; _i <= z->GetModuleCount(); _i++) { \
if (z->Config->implement_lists[_i][y]) \
try \
{ \
z->modules[_i]->x ; \
} \
catch (CoreException& modexcept) \
{ \
z->Log(DEFAULT,"Exception cought: %s",modexcept.GetReason()); \
} \
} \
}
/**
* This define is similar to the one above but returns a result in MOD_RESULT.
* The first module to return a nonzero result is the value to be accepted,
* and any modules after are ignored.
*/
#define FOREACH_RESULT(y,x) { if (ServerInstance->Config->global_implementation[y] > 0) { \
MOD_RESULT = 0; \
for (int _i = 0; _i <= ServerInstance->GetModuleCount(); _i++) { \
if (ServerInstance->Config->implement_lists[_i][y]) { \
try \
{ \
int res = ServerInstance->modules[_i]->x ; \
if (res != 0) { \
MOD_RESULT = res; \
break; \
} \
} \
catch (CoreException& modexcept) \
{ \
ServerInstance->Log(DEFAULT,"Exception cought: %s",modexcept.GetReason()); \
} \
} \
} \
} \
}
/**
* This define is similar to the one above but returns a result in MOD_RESULT.
* The first module to return a nonzero result is the value to be accepted,
* and any modules after are ignored.
*/
#define FOREACH_RESULT_I(z,y,x) { if (z->Config->global_implementation[y] > 0) { \
MOD_RESULT = 0; \
for (int _i = 0; _i <= z->GetModuleCount(); _i++) { \
if (z->Config->implement_lists[_i][y]) { \
try \
{ \
int res = z->modules[_i]->x ; \
if (res != 0) { \
MOD_RESULT = res; \
break; \
} \
} \
catch (CoreException& modexcept) \
{ \
z->Log(DEBUG,"Exception cought: %s",modexcept.GetReason()); \
} \
} \
} \
} \
}
/** Represents a non-local user.
* (in fact, any FD less than -1 does)
*/
#define FD_MAGIC_NUMBER -42
/* Useful macros */
#ifdef WINDOWS
/** Is a local user */
#define IS_LOCAL(x) ((x->GetFd() > -1))
#else
/** Is a local user */
#define IS_LOCAL(x) ((x->GetFd() > -1) && (x->GetFd() <= MAX_DESCRIPTORS))
#endif
/** Is a remote user */
#define IS_REMOTE(x) (x->GetFd() < 0)
/** Is a module created user */
#define IS_MODULE_CREATED(x) (x->GetFd() == FD_MAGIC_NUMBER)
/** Is an oper */
#define IS_OPER(x) (*x->oper)
/** Is away */
#define IS_AWAY(x) (*x->awaymsg)
/** Holds a module's Version information.
* The four members (set by the constructor only) indicate details as to the version number
* of a module. A class of type Version is returned by the GetVersion method of the Module class.
* The flags and API values represent the module flags and API version of the module.
* The API version of a module must match the API version of the core exactly for the module to
* load successfully.
*/
class CoreExport Version : public classbase
{
public:
/** Version numbers, build number, flags and API version
*/
const int Major, Minor, Revision, Build, Flags, API;
/** Initialize version class
*/
Version(int major, int minor, int revision, int build, int flags, int api_ver);
};
/** 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 CoreExport ModuleMessage : public Extensible
{
public:
/** Destructor
*/
virtual ~ModuleMessage() {};
};
/** 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 CoreExport Request : public ModuleMessage
{
protected:
/** 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 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
* 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,
* 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);
/** Fetch the Request data
*/
char* GetData();
/** Fetch the ID string
*/
const char* GetId();
/** 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 CoreExport 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, const 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(InspIRCd* ServerInstance);
};
/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception.
* When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or
* a class derived from ModuleException. If a module throws an exception during its constructor, the module will not
* 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 CoreExport CoreException : public std::exception
{
protected:
/** Holds the error message to be displayed
*/
const std::string err;
/** Source of the exception
*/
const std::string source;
public:
/** Default constructor, just uses the error mesage 'Core threw an exception'.
*/
CoreException() : err("Core threw an exception"), source("The core") {}
/** This constructor can be used to specify an error message before throwing.
*/
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 ~CoreException() throw() {};
/** Returns the reason for the exception.
* The module should probably put something informative here as the user will see this upon failure.
*/
virtual const char* GetReason()
{
return err.c_str();
}
virtual const char* GetSource()
{
return source.c_str();
}
};
class CoreExport 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()
*/
enum Priority { PRIORITY_FIRST, PRIORITY_DONTCARE, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER };
/** Implementation-specific flags which may be set in Module::Implements()
*/
enum Implementation { I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart, I_OnRehash, I_OnServerRaw,
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_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_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_OnWhoisLine, I_OnBuildExemptList, I_OnRawSocketConnect, I_OnGarbageCollect, I_OnBufferFlushed };
/** 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
* instantiated by the ModuleFactory class (see relevent section) for the module to be initialised.
*/
class CoreExport Module : public Extensible
{
protected:
/** Creator/owner pointer
*/
InspIRCd* ServerInstance;
public:
/** Default constructor.
* Creates a module class.
* @param Me An instance of the InspIRCd class which will be saved into ServerInstance for your use
* \exception ModuleException Throwing this class, or any class derived from ModuleException, causes loading of the module to abort.
*/
Module(InspIRCd* Me);
/** Default destructor.
* destroys a module class
*/
virtual ~Module();
/** Returns the version number of a Module.
* The method should return a Version object with its version information assigned via
* Version::Version
*/
virtual Version GetVersion();
/** The Implements function specifies which methods a module should receive events for.
* The char* parameter passed to this function contains a set of true or false values
* (1 or 0) which indicate wether each function is implemented. You must use the Iimplementation
* enum (documented elsewhere on this page) to mark functions as active. For example, to
* receive events for OnUserJoin():
*
* Implements[I_OnUserJoin] = 1;
*
* @param The implement list
*/
virtual void Implements(char* Implements);
/** Used to set the 'priority' of a module (e.g. when it is called in relation to other modules.
* Some modules prefer to be called before other modules, due to their design. For example, a
* module which is expected to operate on complete information would expect to be placed last, so
* that any other modules which wish to adjust that information would execute before it, to be sure
* its information is correct. You can change your module's priority by returning one of:
*
* PRIORITY_FIRST - To place your module first in the list
*
* PRIORITY_LAST - To place your module last in the list
*
* PRIORITY_DONTCARE - To leave your module as it is (this is the default value, if you do not implement this function)
*
* The result of InspIRCd::PriorityBefore() - To move your module before another named module
*
* The result of InspIRCd::PriorityLast() - To move your module after another named module
*
* For a good working example of this method call, please see src/modules/m_spanningtree.cpp
* and src/modules/m_hostchange.so which make use of it. It is highly recommended that unless
* your module has a real need to reorder its priority, it should not implement this function,
* as many modules changing their priorities can make the system redundant.
*/
virtual Priority Prioritize();
/** Called when a user connects.
* The details of the connecting user are available to you in the parameter userrec *user
* @param user The user who is connecting
*/
virtual void OnUserConnect(userrec* user);
/** 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.
* @param user The user who is quitting
* @param message The user's quit message (as seen by non-opers)
* @param oper_message The user's quit message (as seen by opers)
*/
virtual void OnUserQuit(userrec* user, const std::string &message, const std::string &oper_message);
/** 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.
* @param user The user who is disconnecting
*/
virtual void OnUserDisconnect(userrec* user);
/** Called whenever a channel is deleted, either by QUIT, KICK or PART.
* @param chan The channel being deleted
*/
virtual void OnChannelDelete(chanrec* chan);
/** 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
* @param user The user who is joining
* @param channel The channel being joined
* @param silent Change this to true if you want to conceal the JOIN command from the other users
* of the channel (useful for modules such as auditorium)
*/
virtual void OnUserJoin(userrec* user, chanrec* channel, bool &silent);
/** Called after a user joins a channel
* Identical to OnUserJoin, but called immediately afterwards, when any linking module has
* seen the join.
* @param user The user who is joining
* @param channel The channel being joined
*/
virtual void OnPostJoin(userrec* user, chanrec* channel);
/** Called when a user parts a channel.
* The details of the leaving user are available to you in the parameter userrec *user,
* and the details of the channel they have left is available in the variable chanrec *channel
* @param user The user who is parting
* @param channel The channel being parted
* @param partmessage The part message, or an empty string
* @param silent Change this to true if you want to conceal the PART command from the other users
* of the channel (useful for modules such as auditorium)
*/
virtual void OnUserPart(userrec* user, chanrec* channel, const std::string &partmessage, bool &silent);
/** 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.
*/
virtual void OnRehash(userrec* user, const std::string ¶meter);
/** 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
* data which is passing through a connected socket. If you wish, you may munge this data by changing
* the string parameter "raw". If you do this, after your function exits it will immediately be
* cut down to 510 characters plus a carriage return and linefeed. For INBOUND messages only (where
* inbound is set to true) the value of user will be the userrec of the connection sending the
* data. This is not possible for outbound data because the data may be being routed to multiple targets.
* @param raw The raw string in RFC1459 format
* @param inbound A flag to indicate wether the data is coming into the daemon or going out to the user
* @param user The user record sending the text, when inbound == true.
*/
virtual void OnServerRaw(std::string &raw, bool inbound, userrec* user);
/** Called whenever a user is about to join a channel, before any processing is done.
* 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. This is useful for modules which may want to mimic +b, +k, +l etc. Returning -1 from
* this function forces the join to be allowed, bypassing restrictions such as banlists, invite, keys etc.
*
* IMPORTANT NOTE!
*
* If the user joins a NEW channel which does not exist yet, OnUserPreJoin will be called BEFORE the channel
* record is created. This will cause chanrec* chan to be NULL. There is very little you can do in form of
* processing on the actual channel record at this point, however the channel NAME will still be passed in
* char* cname, so that you could for example implement a channel blacklist or whitelist, etc.
* @param user The user joining the channel
* @param chan If the channel is a new channel, this will be NULL, otherwise it will be a pointer to the channel being joined
* @param cname The channel name being joined. For new channels this is valid where chan is not.
* @param privs A string containing the users privilages when joining the channel. For new channels this will contain "@".
* You may alter this string to alter the user's modes on the channel.
* @return 1 To prevent the join, 0 to allow it.
*/
virtual int OnUserPreJoin(userrec* user, chanrec* chan, const char* cname, std::string &privs);
/** 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.
* @param source The user issuing the kick
* @param user The user being kicked
* @param chan The channel the user is being kicked from
* @param reason The kick reason
* @return 1 to prevent the kick, 0 to continue normally, -1 to explicitly allow the kick regardless of normal operation
*/
virtual int OnUserPreKick(userrec* source, userrec* user, chanrec* chan, const 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.
* @param source The user issuing the kick
* @param user The user being kicked
* @param chan The channel the user is being kicked from
* @param reason The kick reason
* @param silent Change this to true if you want to conceal the PART command from the other users
* of the channel (useful for modules such as auditorium)
*/
virtual void OnUserKick(userrec* source, userrec* user, chanrec* chan, const std::string &reason, bool &silent);
/** 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.
* @param user The user who is opering up
* @param opertype The opers type name
*/
virtual void OnOper(userrec* user, const std::string &opertype);
/** Called after a user opers locally.
* This is identical to Module::OnOper(), except it is called after OnOper so that other modules
* can be gauranteed to already have processed the oper-up, for example m_spanningtree has sent
* out the OPERTYPE, etc.
* @param user The user who is opering up
* @param opertype The opers type name
*/
virtual void OnPostOper(userrec* user, const std::string &opertype);
/** Called whenever a user types /INFO.
* The userrec will contain the information of the user who typed the command. Modules may use this
* method to output their own credits in /INFO (which is the ircd's version of an about box).
* It is purposefully not possible to modify any info that has already been output, or halt the list.
* You must write a 371 numeric to the user, containing your info in the following format:
*
* <nick> :information here
*
* @param user The user issuing /INFO
*/
virtual void OnInfo(userrec* user);
/** Called whenever a /WHOIS is performed on a local user.
* The source parameter contains the details of the user who issued the WHOIS command, and
* the dest parameter contains the information of the user they are whoising.
* @param source The user issuing the WHOIS command
* @param dest The user who is being WHOISed
*/
virtual void OnWhois(userrec* source, userrec* dest);
/** Called whenever a user is about to invite another user into a channel, before any processing is done.
* Returning 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. This is useful for modules which may want to filter invites to channels.
* @param source The user who is issuing the INVITE
* @param dest The user being invited
* @param channel The channel the user is being invited to
* @return 1 to deny the invite, 0 to allow
*/
virtual int OnUserPreInvite(userrec* source,userrec* dest,chanrec* channel);
/** Called after a user has been successfully invited to a channel.
* You cannot prevent the invite from occuring using this function, to do that,
* use OnUserPreInvite instead.
* @param source The user who is issuing the INVITE
* @param dest The user being invited
* @param channel The channel the user is being invited to
*/
virtual void OnUserInvite(userrec* source,userrec* dest,chanrec* channel);
/** Called whenever a user is about to PRIVMSG A user or a channel, before any processing is done.
* Returning any nonzero value 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. This is useful for modules which may want to filter or redirect messages.
* target_type can be one of TYPE_USER or TYPE_CHANNEL. If the target_type value is a user,
* you must cast dest to a userrec* otherwise you must cast it to a chanrec*, this is the details
* of where the message is destined to be sent.
* @param user The user sending the message
* @param dest The target of the message (chanrec* or userrec*)
* @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, 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
* output to be sent to the user by the core. If you do this you must produce your own numerics,
* notices etc. This is useful for modules which may want to filter or redirect messages.
* target_type can be one of TYPE_USER or TYPE_CHANNEL. If the target_type value is a user,
* you must cast dest to a userrec* otherwise you must cast it to a chanrec*, this is the details
* of where the message is destined to be sent.
* You may alter the message text as you wish before relinquishing control to the next module
* in the chain, and if no other modules block the text this altered form of the text will be sent out
* to the user and possibly to other servers.
* @param user The user sending the message
* @param dest The target of the message (chanrec* or userrec*)
* @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, 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
* NOT make any changes to the userrec if the user is a remote user as this may cause a desnyc.
* check user->server before taking any action (including returning nonzero from the method).
* If your method returns nonzero, the nickchange is silently forbidden, and it is down to your
* module to generate some meaninful output.
* @param user The username changing their nick
* @param newnick Their new nickname
* @return 1 to deny the change, 0 to allow
*/
virtual int OnUserPreNick(userrec* user, const std::string &newnick);
/** Called after any PRIVMSG sent from a user.
* The dest variable contains a userrec* if target_type is TYPE_USER and a chanrec*
* if target_type is TYPE_CHANNEL.
* @param user The user sending the message
* @param dest The target of the message
* @param target_type The type of target (TYPE_USER or TYPE_CHANNEL)
* @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, 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*
* if target_type is TYPE_CHANNEL.
* @param user The user sending the message
* @param dest The target of the message
* @param target_type The type of target (TYPE_USER or TYPE_CHANNEL)
* @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, 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*
* if target_type is TYPE_CHANNEL. The text variable contains the remainder of the
* mode string after the target, e.g. "+wsi" or "+ooo nick1 nick2 nick3".
* @param user The user sending the MODEs
* @param dest The target of the modes (userrec* or chanrec*)
* @param target_type The type of target (TYPE_USER or TYPE_CHANNEL)
* @param text The actual modes and their parameters if any
*/
virtual void OnMode(userrec* user, void* dest, int target_type, const std::string &text);
/** Allows modules to alter or create server descriptions
* Whenever a module requires a server description, for example for display in
* WHOIS, this function is called in all modules. You may change or define the
* description given in std::string &description. If you do, this description
* will be shown in the WHOIS fields.
* @param servername The servername being searched for
* @param description Alterable server description for this server
*/
virtual void OnGetServerDescription(const std::string &servername,std::string &description);
/** Allows modules to synchronize data which relates to users during a netburst.
* When this function is called, it will be called from the module which implements
* 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!
* @param user The user 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!
*/
virtual void OnSyncUser(userrec* user, Module* proto, void* opaque);
/** Allows modules to synchronize data which relates to channels during a netburst.
* When this function is called, it will be called from the module which implements
* 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!
*
* For a good example of how to use this function, please see src/modules/m_chanprotect.cpp
*
* @param chan The channel 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!
*/
virtual void OnSyncChannel(chanrec* 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 userrec or chanrec 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(chanrec* 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 userrec or chanrec 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(userrec* 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 userrec or chanrec 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 proto A pointer to the module handling network protocol
* @param opaque An opaque pointer set by the protocol module, should not be modified!
* @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);
/** 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.
* @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL
* @param target The chanrec* or userrec* that data should be added to
* @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);
/** Implemented by modules which provide the ability to link servers.
* These modules will implement this method, which allows transparent sending of servermodes
* down the network link as a broadcast, without a module calling it having to know the format
* of the MODE command before the actual mode string.
*
* More documentation to follow soon. Please see src/modules/m_chanprotect.cpp for examples
* of how to use this function.
*
* @param opaque An opaque pointer set by the protocol module, should not be modified!
* @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL
* @param target The chanrec* or userrec* that modes should be sent for
* @param modeline The modes and parameters to be sent
*/
virtual void ProtoSendMode(void* opaque, int target_type, void* target, const std::string &modeline);
/** Implemented by modules which provide the ability to link servers.
* These modules will implement this method, which allows metadata (extra data added to
* user and channel records using class Extensible, Extensible::Extend, etc) to be sent
* to other servers on a netburst and decoded at the other end by the same module on a
* different server.
*
* More documentation to follow soon. Please see src/modules/m_swhois.cpp for example of
* how to use this function.
* @param opaque An opaque pointer set by the protocol module, should not be modified!
* @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL
* @param target The chanrec* or userrec* that metadata should be sent for
* @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, int target_type, void* target, const std::string &extname, const std::string &extdata);
/** Called after every WALLOPS command.
* @param user The user sending the WALLOPS
* @param text The content of the WALLOPS message
*/
virtual void OnWallops(userrec* user, const std::string &text);
/** Called whenever a user's hostname is changed.
* This event triggers after the host has been set.
* @param user The user whos host is being changed
* @param newhost The new hostname being set
*/
virtual void OnChangeHost(userrec* user, const std::string &newhost);
/** Called whenever a user's GECOS (realname) is changed.
* This event triggers after the name has been set.
* @param user The user who's GECOS is being changed
* @param gecos The new GECOS being set on the user
*/
virtual void OnChangeName(userrec* user, const std::string &gecos);
/** Called whenever a gline is added by a local user.
* This method is triggered after the line is added.
* @param duration The duration of the line in seconds
* @param source The sender of the line
* @param reason The reason text to be displayed
* @param hostmask The hostmask to add
*/
virtual void OnAddGLine(long duration, userrec* source, const std::string &reason, const std::string &hostmask);
/** Called whenever a zline is added by a local user.
* This method is triggered after the line is added.
* @param duration The duration of the line in seconds
* @param source The sender of the line
* @param reason The reason text to be displayed
* @param ipmask The hostmask to add
*/
virtual void OnAddZLine(long duration, userrec* source, const std::string &reason, const std::string &ipmask);
/** Called whenever a kline is added by a local user.
* This method is triggered after the line is added.
* @param duration The duration of the line in seconds
* @param source The sender of the line
* @param reason The reason text to be displayed
* @param hostmask The hostmask to add
*/
virtual void OnAddKLine(long duration, userrec* source, const std::string &reason, const std::string &hostmask);
/** Called whenever a qline is added by a local user.
* This method is triggered after the line is added.
* @param duration The duration of the line in seconds
* @param source The sender of the line
* @param reason The reason text to be displayed
* @param nickmask The hostmask to add
*/
virtual void OnAddQLine(long duration, userrec* source, const std::string &reason, const std::string &nickmask);
/** Called whenever a eline is added by a local user.
* This method is triggered after the line is added.
* @param duration The duration of the line in seconds
* @param source The sender of the line
* @param reason The reason text to be displayed
* @param hostmask The hostmask to add
*/
virtual void OnAddELine(long duration, userrec* source, const std::string &reason, const std::string &hostmask);
/** Called whenever a gline is deleted.
* This method is triggered after the line is deleted.
* @param source The user removing the line
* @param hostmask The hostmask to delete
*/
virtual void OnDelGLine(userrec* source, const std::string &hostmask);
/** Called whenever a zline is deleted.
* This method is triggered after the line is deleted.
* @param source The user removing the line
* @param hostmask The hostmask to delete
*/
virtual void OnDelZLine(userrec* source, const std::string &ipmask);
/** Called whenever a kline is deleted.
* This method is triggered after the line is deleted.
* @param source The user removing the line
* @param hostmask The hostmask to delete
*/
virtual void OnDelKLine(userrec* source, const std::string &hostmask);
/** Called whenever a qline is deleted.
* This method is triggered after the line is deleted.
* @param source The user removing the line
* @param hostmask The hostmask to delete
*/
virtual void OnDelQLine(userrec* source, const std::string &nickmask);
/** Called whenever a eline is deleted.
* This method is triggered after the line is deleted.
* @param source The user removing the line
* @param hostmask The hostmask to delete
*/
virtual void OnDelELine(userrec* source, const std::string &hostmask);
/** Called before your module is unloaded to clean up Extensibles.
* This method is called once for every user and channel on the network,
* so that when your module unloads it may clear up any remaining data
* in the form of Extensibles added using Extensible::Extend().
* If the target_type variable is TYPE_USER, then void* item refers to
* a userrec*, otherwise it refers to a chanrec*.
* @param target_type The type of item being cleaned
* @param item A pointer to the item's class
*/
virtual void OnCleanup(int target_type, void* item);
/** Called after any nickchange, local or remote. This can be used to track users after nickchanges
* have been applied. Please note that although you can see remote nickchanges through this function, you should
* NOT make any changes to the userrec if the user is a remote user as this may cause a desnyc.
* check user->server before taking any action (including returning nonzero from the method).
* Because this method is called after the nickchange is taken place, no return values are possible
* to indicate forbidding of the nick change. Use OnUserPreNick for this.
* @param user The user changing their nick
* @param oldnick The old nickname of the user before the nickchange
*/
virtual void OnUserPostNick(userrec* user, const std::string &oldnick);
/** Called before an action which requires a channel privilage check.
* This function is called before many functions which check a users status on a channel, for example
* before opping a user, deopping a user, kicking a user, etc.
* There are several values for access_type which indicate for what reason access is being checked.
* These are:<br><br>
* AC_KICK (0) - A user is being kicked<br>
* AC_DEOP (1) - a user is being deopped<br>
* AC_OP (2) - a user is being opped<br>
* AC_VOICE (3) - a user is being voiced<br>
* AC_DEVOICE (4) - a user is being devoiced<br>
* AC_HALFOP (5) - a user is being halfopped<br>
* AC_DEHALFOP (6) - a user is being dehalfopped<br>
* AC_INVITE () - a user is being invited<br>
* AC_GENERAL_MODE (8) - a user channel mode is being changed<br><br>
* Upon returning from your function you must return either ACR_DEFAULT, to indicate the module wishes
* to do nothing, or ACR_DENY where approprate to deny the action, and ACR_ALLOW where appropriate to allow
* the action. Please note that in the case of some access checks (such as AC_GENERAL_MODE) access may be
* denied 'upstream' causing other checks such as AC_DEOP to not be reached. Be very careful with use of the
* AC_GENERAL_MODE type, as it may inadvertently override the behaviour of other modules. When the access_type
* is AC_GENERAL_MODE, the destination of the mode will be NULL (as it has not yet been determined).
* @param source The source of the access check
* @param dest The destination of the access check
* @param channel The channel which is being checked
* @param access_type See above
*/
virtual int OnAccessCheck(userrec* source,userrec* dest,chanrec* channel,int access_type);
/** Called when a 005 numeric is about to be output.
* The module should modify the 005 numeric if needed to indicate its features.
* @param output The 005 string to be modified if neccessary.
*/
virtual void On005Numeric(std::string &output);
/** Called when a client is disconnected by KILL.
* If a client is killed by a server, e.g. a nickname collision or protocol error,
* source is NULL.
* Return 1 from this function to prevent the kill, and 0 from this function to allow
* it as normal. If you prevent the kill no output will be sent to the client, it is
* down to your module to generate this information.
* NOTE: It is NOT advisable to stop kills which originate from servers or remote users.
* If you do so youre risking race conditions, desyncs and worse!
* @param source The user sending the KILL
* @param dest The user being killed
* @param reason The kill reason
* @return 1 to prevent the kill, 0 to allow
*/
virtual int OnKill(userrec* source, userrec* dest, const std::string &reason);
/** Called when an oper wants to disconnect a remote user via KILL
* @param source The user sending the KILL
* @param dest The user being killed
* @param reason The kill reason
*/
virtual void OnRemoteKill(userrec* source, userrec* dest, const std::string &reason, const std::string &operreason);
/** Called whenever a module is loaded.
* mod will contain a pointer to the module, and string will contain its name,
* for example m_widgets.so. This function is primary for dependency checking,
* your module may decide to enable some extra features if it sees that you have
* for example loaded "m_killwidgets.so" with "m_makewidgets.so". It is highly
* recommended that modules do *NOT* bail if they cannot satisfy dependencies,
* but instead operate under reduced functionality, unless the dependency is
* absolutely neccessary (e.g. a module that extends the features of another
* module).
* @param mod A pointer to the new module
* @param name The new module's filename
*/
virtual void OnLoadModule(Module* mod,const std::string &name);
/** Called whenever a module is unloaded.
* mod will contain a pointer to the module, and string will contain its name,
* for example m_widgets.so. This function is primary for dependency checking,
* your module may decide to enable some extra features if it sees that you have
* for example loaded "m_killwidgets.so" with "m_makewidgets.so". It is highly
* recommended that modules do *NOT* bail if they cannot satisfy dependencies,
* but instead operate under reduced functionality, unless the dependency is
* absolutely neccessary (e.g. a module that extends the features of another
* module).
* @param mod Pointer to the module being unloaded (still valid)
* @param name The filename of the module being unloaded
*/
virtual void OnUnloadModule(Module* mod,const 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.
* @param curtime The current timer derived from time(2)
*/
virtual void OnBackgroundTimer(time_t curtime);
/** 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, and for invalid commands. Invalid commands may only be sent to this
* function when the value of validated is false. 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
* InspIRCd::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!)
* @param command The command being executed
* @param parameters An array of array of characters containing the parameters for the command
* @param pcnt The nuimber of parameters passed to the command
* @param user the user issuing the command
* @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.
* @param original_line The entire original line as passed to the parser from the user
* @return 1 to block the command, 0 to allow
*/
virtual int OnPreCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, bool validated, const std::string &original_line);
/** Called after any command has been 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). The result code returned by the command handler is
* provided.
* @param command The command being executed
* @param parameters An array of array of characters containing the parameters for the command
* @param pcnt The nuimber of parameters passed to the command
* @param user the user issuing the command
* @param result The return code given by the command handler, one of CMD_SUCCESS or CMD_FAILURE
* @param original_line The entire original line as passed to the parser from the user
*/
virtual void OnPostCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, CmdResult result, const std::string &original_line);
/** 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.
* @param user The user to check
* @return true to indicate readiness, false if otherwise
*/
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.
* @param user The user registering
* @return 1 to indicate user quit, 0 to continue
*/
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
* 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.
* @param user The user joining the channel
* @param chan The channel being joined
* @return 1 to explicitly allow the join, 0 to proceed as normal
*/
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.
* @param user The user joining the channel
* @param chan The channel being joined
* @return 1 to explicitly allow the join, 0 to proceed as normal
*/
virtual int OnCheckKey(userrec* user, chanrec* chan, const 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.
* @param user The user joining the channel
* @param chan The channel being joined
* @return 1 to explicitly allow the join, 0 to proceed as normal
*/
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.
* @param user The user joining the channel
* @param chan The channel being joined
* @return 1 to explicitly allow the join, 0 to proceed as normal
*/
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.
* @param symbol the symbol provided to /STATS
* @param user the user issuing the /STATS command
* @param results A string_list to append results into. You should put all your results
* into this string_list, rather than displaying them directly, so that your handler will
* work when remote STATS queries are received.
* @return 1 to block the /STATS from being processed by the core, 0 to allow it
*/
virtual int OnStats(char symbol, userrec* user, string_list &results);
/** Called whenever a change of a local users displayed host is attempted.
* Return 1 to deny the host change, or 0 to allow it.
* @param user The user whos host will be changed
* @param newhost The new hostname
* @return 1 to deny the host change, 0 to allow
*/
virtual int OnChangeLocalUserHost(userrec* user, const 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.
* @param user The user whos GECOS will be changed
* @param newhost The new GECOS
* @return 1 to deny the GECOS change, 0 to allow
*/
virtual int OnChangeLocalUserGECOS(userrec* user, const 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.
* @param user The user changing the topic
* @param chan The channels who's topic is being changed
* @param topic The actual topic text
* @param 1 to block the topic change, 0 to allow
*/
virtual int OnLocalTopicChange(userrec* user, chanrec* chan, const std::string &topic);
/** Called whenever a local topic has been changed.
* To block topic changes you must use OnLocalTopicChange instead.
* @param user The user changing the topic
* @param chan The channels who's topic is being changed
* @param topic The actual topic text
*/
virtual void OnPostLocalTopicChange(userrec* user, chanrec* chan, const std::string &topic);
/** 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!
* @param event The Event class being received
*/
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).
* @param request The Request class being received
*/
virtual char* OnRequest(Request* request);
/** Called whenever an oper password is to be compared to what a user has input.
* The password field (from the config file) is in 'password' and is to be compared against
* 'input'. This method allows for encryption of oper passwords and much more besides.
* You should return a nonzero value if you want to allow the comparison or zero if you wish
* to do nothing.
* @param password The oper's password
* @param input The password entered
* @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, 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
* such a task must be performed by another server. You can however bounce modes by sending
* servermodes out to reverse mode changes.
* @param user The user who is opering
*/
virtual void OnGlobalOper(userrec* user);
/** Called after a user has fully connected and all modules have executed OnUserConnect
* This event is informational only. You should not change any user information in this
* event. To do so, use the OnUserConnect method to change the state of local users.
* This is called for both local and remote users.
* @param user The user who is connecting
*/
virtual void OnPostConnect(userrec* user);
/** Called whenever a ban is added to a channel's list.
* Return a non-zero value to 'eat' the mode change and prevent the ban from being added.
* @param source The user adding the ban
* @param channel The channel the ban is being added to
* @param banmask The ban mask being added
* @return 1 to block the ban, 0 to continue as normal
*/
virtual int OnAddBan(userrec* source, chanrec* channel,const std::string &banmask);
/** Called whenever a ban is removed from a channel's list.
* Return a non-zero value to 'eat' the mode change and prevent the ban from being removed.
* @param source The user deleting the ban
* @param channel The channel the ban is being deleted from
* @param banmask The ban mask being deleted
* @return 1 to block the unban, 0 to continue as normal
*/
virtual int OnDelBan(userrec* source, chanrec* channel,const std::string &banmask);
/** 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
* no information relating to a user record as the connection has not been assigned yet.
* 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 localport The local port number the user connected to
*/
virtual void OnRawSocketAccept(int fd, const std::string &ip, int localport);
/** 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
* for use by modules which may wrap connections within another API such as SSL for example.
* return a non-zero result if you have handled the write operation, in which case the core
* will not call write().
* @param fd The file descriptor of the socket
* @param buffer A char* buffer being written
* @param Number of characters to write
* @return Number of characters actually written or 0 if you didn't handle the operation
*/
virtual int OnRawSocketWrite(int fd, const char* buffer, int count);
/** Called immediately before any socket is closed. When this event is called, shutdown()
* has not yet been called on the socket.
* @param fd The file descriptor of the socket prior to close()
*/
virtual void OnRawSocketClose(int fd);
/** Called immediately upon connection of an outbound InspSocket which has been hooked
* by a module.
* @param fd The file descriptor of the socket immediately after connect()
*/
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.
* Your event should return 1 if it has handled the reading itself, which prevents the core
* just using read(). You should place any data read into buffer, up to but NOT GREATER THAN
* the value of count. The value of readresult must be identical to an actual result that might
* be returned from the read() system call, for example, number of bytes read upon success,
* 0 upon EOF or closed socket, and -1 for error. If your function returns a nonzero value,
* you MUST set readresult.
* @param fd The file descriptor of the socket
* @param buffer A char* buffer being read to
* @param count The size of the buffer
* @param readresult The amount of characters read, or 0
* @return nonzero if the event was handled, in which case readresult must be valid on exit
*/
virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult);
/** Called whenever a user sets away.
* This method has no parameter for the away message, as it is available in the
* user record as userrec::awaymsg.
* @param user The user setting away
*/
virtual void OnSetAway(userrec* user);
/** Called when a user cancels their away state.
* @param user The user returning from away
*/
virtual void OnCancelAway(userrec* user);
/** Called whenever a NAMES list is requested.
* You can produce the nameslist yourself, overriding the current list,
* and if you do you must return 1. If you do not handle the names list,
* return 0.
* @param The user requesting the NAMES list
* @param Ptr The channel the NAMES list is requested for
* @param userlist The user list for the channel (you may change this pointer.
* If you want to change the values, take a copy first, and change the copy, then
* point the pointer at your copy)
* @return 1 to prevent the user list being sent to the client, 0 to allow it
*/
virtual int OnUserList(userrec* user, chanrec* Ptr, CUList* &userlist);
/** 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();
/** Called whenever a user's write buffer has been completely sent.
* This is called when the user's write buffer is completely empty, and
* there are no more pending bytes to be written and no pending write events
* in the socket engine's queue. This may be used to refill the buffer with
* data which is being spooled in a controlled manner, e.g. LIST lines.
* @param user The user who's buffer is now empty.
*/
virtual void OnBufferFlushed(userrec* user);
};
#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.
* Constructing the class using one parameter allows you to specify a path to your own configuration
* file, otherwise, inspircd.conf is read.
*/
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;
public:
/** Default constructor.
* This constructor initialises the ConfigReader class to read the inspircd.conf file
* 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.
*/
~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, 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
* 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
*/
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.
*/
long GetError();
/** Counts the number of times a given tag appears in the config file.
* This method counts the number of times a tag appears in a config file, for use where
* there are several tags of the same kind, e.g. with opers and connect types. It can be
* used with the index value of ConfigReader::ReadValue to loop through all copies of a
* 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,userrec* user);
/** Returns the number of items within a tag.
* For example if the tag was <test tag="blah" data="foo"> then this
* function would return 2. Spaces and newlines both qualify as valid seperators
* between values.
*/
int EnumerateValues(const std::string &tag, int index);
};
/** Caches a text file into memory and can be used to retrieve lines from it.
* This class contains methods for read-only manipulation of a text file in memory.
* Either use the constructor type with one parameter to load a file into memory
* at construction, or use the LoadFile method to load a file.
*/
class CoreExport FileReader : public classbase
{
InspIRCd* ServerInstance;
/** The file contents
*/
file_cache fc;
/** Content size in bytes
*/
unsigned long contentsize;
/** Calculate content size in bytes
*/
void CalcSize();
public:
/** Default constructor.
* This method does not load any file into memory, you must use the LoadFile method
* after constructing the class this way.
*/
FileReader(InspIRCd* Instance);
/** Secondary constructor.
* This method initialises the class with a file loaded into it ready for GetLine and
* and other methods to be called. If the file could not be loaded, FileReader::FileSize
* returns 0.
*/
FileReader(InspIRCd* Instance, const std::string &filename);
/** Default destructor.
* This deletes the memory allocated to the file.
*/
~FileReader();
/** Used to load a file.
* This method loads a file into the class ready for GetLine and
* and other methods to be called. If the file could not be loaded, FileReader::FileSize
* returns 0.
*/
void LoadFile(const std::string &filename);
/** Returns the whole content of the file as std::string
*/
std::string Contents();
/** Returns the entire size of the file as std::string
*/
unsigned long ContentSize();
/** Returns true if the file exists
* This function will return false if the file could not be opened.
*/
bool Exists();
/** Retrieve one line from the file.
* This method retrieves one line from the text file. If an empty non-NULL string is returned,
* the index was out of bounds, or the line had no data on it.
*/
std::string GetLine(int x);
/** Returns the size of the file in lines.
* This method returns the number of lines in the read file. If it is 0, no lines have been
* read into memory, either because the file is empty or it does not exist, or cannot be
* opened due to permission problems.
*/
int FileSize();
};
/** Instantiates classes inherited from Module.
* This class creates a class inherited from type Module, using new. This is to allow for modules
* to create many different variants of Module, dependent on architecture, configuration, etc.
* In most cases, the simple class shown in the example module m_foobar.so will suffice for most
* modules.
*/
class CoreExport ModuleFactory : public classbase
{
public:
/** The default constructor does nothing.
*/
ModuleFactory() { }
/** The default destructor does nothing
*/
virtual ~ModuleFactory() { }
/** Creates a new module.
* Your inherited class of ModuleFactory must return a pointer to your Module class
* using this method.
*/
virtual Module * CreateModule(InspIRCd* Me) = 0;
};
/** A DLLFactory (designed to load shared objects) containing a ModuleFactory.
*/
typedef DLLFactory<ModuleFactory> ircd_module;
/** A list of loaded Modules
*/
typedef std::vector<Module*> ModuleList;
/** A list of loaded ModuleFactories
*/
typedef std::vector<ircd_module*> FactoryList;
/** This definition is used as shorthand for the various classes
* and functions needed to make a module loadable by the OS.
* It defines the class factory and external init_module function.
*/
#define MODULE_INIT(y) \
class Factory : public ModuleFactory \
{ \
public: \
virtual Module * CreateModule(InspIRCd* Me) \
{ \
return new y(Me); \
} \
}; \
extern "C" DllExport void * init_module(void) \
{ \
return new Factory; \
}
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __MODULES_H +#define __MODULES_H + +/** Used with OnAccessCheck() method of modules + */ +enum AccessControlType { + ACR_DEFAULT, // Do default action (act as if the module isnt even loaded) + ACR_DENY, // deny the action + ACR_ALLOW, // allow the action + AC_KICK, // a user is being kicked + AC_DEOP, // a user is being deopped + AC_OP, // a user is being opped + AC_VOICE, // a user is being voiced + AC_DEVOICE, // a user is being devoiced + AC_HALFOP, // a user is being halfopped + AC_DEHALFOP, // a user is being dehalfopped + AC_INVITE, // a user is being invited + AC_GENERAL_MODE // a channel mode is being changed +}; + +/** Used to define a set of behavior bits for a module + */ +enum ModuleFlags { + VF_STATIC = 1, // module is static, cannot be /unloadmodule'd + VF_VENDOR = 2, // module is a vendor module (came in the original tarball, not 3rd party) + VF_SERVICEPROVIDER = 4, // module provides a service to other modules (can be a dependency) + VF_COMMON = 8 // module needs to be common on all servers in a network to link +}; + +/** Used with SendToMode() + */ +enum WriteModeFlags { + WM_AND = 1, + WM_OR = 2 +}; + +/** Used to represent an event type, for user, channel or server + */ +enum TargetTypeFlags { + TYPE_USER = 1, + TYPE_CHANNEL, + TYPE_SERVER, + TYPE_OTHER +}; + +/** Used to represent wether a message was PRIVMSG or NOTICE + */ +enum MessageType { + MSG_PRIVMSG = 0, + MSG_NOTICE = 1 +}; + +#include "globals.h" +#include "dynamic.h" +#include "base.h" +#include "ctables.h" +#include "inspsocket.h" +#include <string> +#include <deque> +#include <sstream> +#include "timer.h" +#include "mode.h" +#include "dns.h" + +/** 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 11025 +#ifdef IPV6 +#define API_VERSION (NATIVE_API_VERSION * 10) +#else +#define API_VERSION (NATIVE_API_VERSION * 1) +#endif + +class ServerConfig; + +/* Forward-delacare module for ModuleMessage etc + */ +class Module; + +/** Low level definition of a FileReader classes file cache area - + * a text file seperated into lines. + */ +typedef std::deque<std::string> file_cache; + +/** A set of strings. + */ +typedef file_cache string_list; + +/** Holds a list of 'published features' for modules. + */ +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.: + * 'FOREACH_MOD(I_OnConnect,OnConnect(user));' + */ +#define FOREACH_MOD(y,x) if (ServerInstance->Config->global_implementation[y] > 0) { \ + for (int _i = 0; _i <= ServerInstance->GetModuleCount(); _i++) { \ + if (ServerInstance->Config->implement_lists[_i][y]) \ + try \ + { \ + ServerInstance->modules[_i]->x ; \ + } \ + catch (CoreException& modexcept) \ + { \ + ServerInstance->Log(DEFAULT,"Exception cought: %s",modexcept.GetReason()); \ + } \ + } \ + } + +/** + * This #define allows us to call a method in all + * loaded modules in a readable simple way and pass + * an instance pointer to the macro. e.g.: + * 'FOREACH_MOD_I(Instance, OnConnect, OnConnect(user));' + */ +#define FOREACH_MOD_I(z,y,x) if (z->Config->global_implementation[y] > 0) { \ + for (int _i = 0; _i <= z->GetModuleCount(); _i++) { \ + if (z->Config->implement_lists[_i][y]) \ + try \ + { \ + z->modules[_i]->x ; \ + } \ + catch (CoreException& modexcept) \ + { \ + z->Log(DEFAULT,"Exception cought: %s",modexcept.GetReason()); \ + } \ + } \ +} +/** + * This define is similar to the one above but returns a result in MOD_RESULT. + * The first module to return a nonzero result is the value to be accepted, + * and any modules after are ignored. + */ +#define FOREACH_RESULT(y,x) { if (ServerInstance->Config->global_implementation[y] > 0) { \ + MOD_RESULT = 0; \ + for (int _i = 0; _i <= ServerInstance->GetModuleCount(); _i++) { \ + if (ServerInstance->Config->implement_lists[_i][y]) { \ + try \ + { \ + int res = ServerInstance->modules[_i]->x ; \ + if (res != 0) { \ + MOD_RESULT = res; \ + break; \ + } \ + } \ + catch (CoreException& modexcept) \ + { \ + ServerInstance->Log(DEFAULT,"Exception cought: %s",modexcept.GetReason()); \ + } \ + } \ + } \ + } \ + } + +/** + * This define is similar to the one above but returns a result in MOD_RESULT. + * The first module to return a nonzero result is the value to be accepted, + * and any modules after are ignored. + */ +#define FOREACH_RESULT_I(z,y,x) { if (z->Config->global_implementation[y] > 0) { \ + MOD_RESULT = 0; \ + for (int _i = 0; _i <= z->GetModuleCount(); _i++) { \ + if (z->Config->implement_lists[_i][y]) { \ + try \ + { \ + int res = z->modules[_i]->x ; \ + if (res != 0) { \ + MOD_RESULT = res; \ + break; \ + } \ + } \ + catch (CoreException& modexcept) \ + { \ + z->Log(DEBUG,"Exception cought: %s",modexcept.GetReason()); \ + } \ + } \ + } \ + } \ +} + +/** Represents a non-local user. + * (in fact, any FD less than -1 does) + */ +#define FD_MAGIC_NUMBER -42 + +/* Useful macros */ +#ifdef WINDOWS +/** Is a local user */ +#define IS_LOCAL(x) ((x->GetFd() > -1)) +#else +/** Is a local user */ +#define IS_LOCAL(x) ((x->GetFd() > -1) && (x->GetFd() <= MAX_DESCRIPTORS)) +#endif +/** Is a remote user */ +#define IS_REMOTE(x) (x->GetFd() < 0) +/** Is a module created user */ +#define IS_MODULE_CREATED(x) (x->GetFd() == FD_MAGIC_NUMBER) +/** Is an oper */ +#define IS_OPER(x) (*x->oper) +/** Is away */ +#define IS_AWAY(x) (*x->awaymsg) + +/** Holds a module's Version information. + * The four members (set by the constructor only) indicate details as to the version number + * of a module. A class of type Version is returned by the GetVersion method of the Module class. + * The flags and API values represent the module flags and API version of the module. + * The API version of a module must match the API version of the core exactly for the module to + * load successfully. + */ +class CoreExport Version : public classbase +{ + public: + /** Version numbers, build number, flags and API version + */ + const int Major, Minor, Revision, Build, Flags, API; + + /** Initialize version class + */ + Version(int major, int minor, int revision, int build, int flags, int api_ver); +}; + +/** 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 CoreExport ModuleMessage : public Extensible +{ + public: + /** Destructor + */ + virtual ~ModuleMessage() {}; +}; + +/** 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 CoreExport Request : public ModuleMessage +{ + protected: + /** 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 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 + * 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, + * 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); + /** Fetch the Request data + */ + char* GetData(); + /** Fetch the ID string + */ + const char* GetId(); + /** 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 CoreExport 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, const 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(InspIRCd* ServerInstance); +}; + +/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception. + * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or + * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not + * 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 CoreExport CoreException : public std::exception +{ + protected: + /** Holds the error message to be displayed + */ + const std::string err; + /** Source of the exception + */ + const std::string source; + public: + /** Default constructor, just uses the error mesage 'Core threw an exception'. + */ + CoreException() : err("Core threw an exception"), source("The core") {} + /** This constructor can be used to specify an error message before throwing. + */ + 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 ~CoreException() throw() {}; + /** Returns the reason for the exception. + * The module should probably put something informative here as the user will see this upon failure. + */ + virtual const char* GetReason() + { + return err.c_str(); + } + + virtual const char* GetSource() + { + return source.c_str(); + } +}; + +class CoreExport 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() + */ +enum Priority { PRIORITY_FIRST, PRIORITY_DONTCARE, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER }; + +/** Implementation-specific flags which may be set in Module::Implements() + */ +enum Implementation { I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart, I_OnRehash, I_OnServerRaw, + 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_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_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_OnWhoisLine, I_OnBuildExemptList, I_OnRawSocketConnect, I_OnGarbageCollect, I_OnBufferFlushed }; + +/** 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 + * instantiated by the ModuleFactory class (see relevent section) for the module to be initialised. + */ +class CoreExport Module : public Extensible +{ + protected: + /** Creator/owner pointer + */ + InspIRCd* ServerInstance; + public: + + /** Default constructor. + * Creates a module class. + * @param Me An instance of the InspIRCd class which will be saved into ServerInstance for your use + * \exception ModuleException Throwing this class, or any class derived from ModuleException, causes loading of the module to abort. + */ + Module(InspIRCd* Me); + + /** Default destructor. + * destroys a module class + */ + virtual ~Module(); + + /** Returns the version number of a Module. + * The method should return a Version object with its version information assigned via + * Version::Version + */ + virtual Version GetVersion(); + + /** The Implements function specifies which methods a module should receive events for. + * The char* parameter passed to this function contains a set of true or false values + * (1 or 0) which indicate wether each function is implemented. You must use the Iimplementation + * enum (documented elsewhere on this page) to mark functions as active. For example, to + * receive events for OnUserJoin(): + * + * Implements[I_OnUserJoin] = 1; + * + * @param The implement list + */ + virtual void Implements(char* Implements); + + /** Used to set the 'priority' of a module (e.g. when it is called in relation to other modules. + * Some modules prefer to be called before other modules, due to their design. For example, a + * module which is expected to operate on complete information would expect to be placed last, so + * that any other modules which wish to adjust that information would execute before it, to be sure + * its information is correct. You can change your module's priority by returning one of: + * + * PRIORITY_FIRST - To place your module first in the list + * + * PRIORITY_LAST - To place your module last in the list + * + * PRIORITY_DONTCARE - To leave your module as it is (this is the default value, if you do not implement this function) + * + * The result of InspIRCd::PriorityBefore() - To move your module before another named module + * + * The result of InspIRCd::PriorityLast() - To move your module after another named module + * + * For a good working example of this method call, please see src/modules/m_spanningtree.cpp + * and src/modules/m_hostchange.so which make use of it. It is highly recommended that unless + * your module has a real need to reorder its priority, it should not implement this function, + * as many modules changing their priorities can make the system redundant. + */ + virtual Priority Prioritize(); + + /** Called when a user connects. + * The details of the connecting user are available to you in the parameter userrec *user + * @param user The user who is connecting + */ + virtual void OnUserConnect(userrec* user); + + /** 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. + * @param user The user who is quitting + * @param message The user's quit message (as seen by non-opers) + * @param oper_message The user's quit message (as seen by opers) + */ + virtual void OnUserQuit(userrec* user, const std::string &message, const std::string &oper_message); + + /** 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. + * @param user The user who is disconnecting + */ + virtual void OnUserDisconnect(userrec* user); + + /** Called whenever a channel is deleted, either by QUIT, KICK or PART. + * @param chan The channel being deleted + */ + virtual void OnChannelDelete(chanrec* chan); + + /** 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 + * @param user The user who is joining + * @param channel The channel being joined + * @param silent Change this to true if you want to conceal the JOIN command from the other users + * of the channel (useful for modules such as auditorium) + */ + virtual void OnUserJoin(userrec* user, chanrec* channel, bool &silent); + + /** Called after a user joins a channel + * Identical to OnUserJoin, but called immediately afterwards, when any linking module has + * seen the join. + * @param user The user who is joining + * @param channel The channel being joined + */ + virtual void OnPostJoin(userrec* user, chanrec* channel); + + /** Called when a user parts a channel. + * The details of the leaving user are available to you in the parameter userrec *user, + * and the details of the channel they have left is available in the variable chanrec *channel + * @param user The user who is parting + * @param channel The channel being parted + * @param partmessage The part message, or an empty string + * @param silent Change this to true if you want to conceal the PART command from the other users + * of the channel (useful for modules such as auditorium) + */ + virtual void OnUserPart(userrec* user, chanrec* channel, const std::string &partmessage, bool &silent); + + /** 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. + */ + virtual void OnRehash(userrec* user, const std::string ¶meter); + + /** 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 + * data which is passing through a connected socket. If you wish, you may munge this data by changing + * the string parameter "raw". If you do this, after your function exits it will immediately be + * cut down to 510 characters plus a carriage return and linefeed. For INBOUND messages only (where + * inbound is set to true) the value of user will be the userrec of the connection sending the + * data. This is not possible for outbound data because the data may be being routed to multiple targets. + * @param raw The raw string in RFC1459 format + * @param inbound A flag to indicate wether the data is coming into the daemon or going out to the user + * @param user The user record sending the text, when inbound == true. + */ + virtual void OnServerRaw(std::string &raw, bool inbound, userrec* user); + + /** Called whenever a user is about to join a channel, before any processing is done. + * 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. This is useful for modules which may want to mimic +b, +k, +l etc. Returning -1 from + * this function forces the join to be allowed, bypassing restrictions such as banlists, invite, keys etc. + * + * IMPORTANT NOTE! + * + * If the user joins a NEW channel which does not exist yet, OnUserPreJoin will be called BEFORE the channel + * record is created. This will cause chanrec* chan to be NULL. There is very little you can do in form of + * processing on the actual channel record at this point, however the channel NAME will still be passed in + * char* cname, so that you could for example implement a channel blacklist or whitelist, etc. + * @param user The user joining the channel + * @param chan If the channel is a new channel, this will be NULL, otherwise it will be a pointer to the channel being joined + * @param cname The channel name being joined. For new channels this is valid where chan is not. + * @param privs A string containing the users privilages when joining the channel. For new channels this will contain "@". + * You may alter this string to alter the user's modes on the channel. + * @return 1 To prevent the join, 0 to allow it. + */ + virtual int OnUserPreJoin(userrec* user, chanrec* chan, const char* cname, std::string &privs); + + /** 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. + * @param source The user issuing the kick + * @param user The user being kicked + * @param chan The channel the user is being kicked from + * @param reason The kick reason + * @return 1 to prevent the kick, 0 to continue normally, -1 to explicitly allow the kick regardless of normal operation + */ + virtual int OnUserPreKick(userrec* source, userrec* user, chanrec* chan, const 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. + * @param source The user issuing the kick + * @param user The user being kicked + * @param chan The channel the user is being kicked from + * @param reason The kick reason + * @param silent Change this to true if you want to conceal the PART command from the other users + * of the channel (useful for modules such as auditorium) + */ + virtual void OnUserKick(userrec* source, userrec* user, chanrec* chan, const std::string &reason, bool &silent); + + /** 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. + * @param user The user who is opering up + * @param opertype The opers type name + */ + virtual void OnOper(userrec* user, const std::string &opertype); + + /** Called after a user opers locally. + * This is identical to Module::OnOper(), except it is called after OnOper so that other modules + * can be gauranteed to already have processed the oper-up, for example m_spanningtree has sent + * out the OPERTYPE, etc. + * @param user The user who is opering up + * @param opertype The opers type name + */ + virtual void OnPostOper(userrec* user, const std::string &opertype); + + /** Called whenever a user types /INFO. + * The userrec will contain the information of the user who typed the command. Modules may use this + * method to output their own credits in /INFO (which is the ircd's version of an about box). + * It is purposefully not possible to modify any info that has already been output, or halt the list. + * You must write a 371 numeric to the user, containing your info in the following format: + * + * <nick> :information here + * + * @param user The user issuing /INFO + */ + virtual void OnInfo(userrec* user); + + /** Called whenever a /WHOIS is performed on a local user. + * The source parameter contains the details of the user who issued the WHOIS command, and + * the dest parameter contains the information of the user they are whoising. + * @param source The user issuing the WHOIS command + * @param dest The user who is being WHOISed + */ + virtual void OnWhois(userrec* source, userrec* dest); + + /** Called whenever a user is about to invite another user into a channel, before any processing is done. + * Returning 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. This is useful for modules which may want to filter invites to channels. + * @param source The user who is issuing the INVITE + * @param dest The user being invited + * @param channel The channel the user is being invited to + * @return 1 to deny the invite, 0 to allow + */ + virtual int OnUserPreInvite(userrec* source,userrec* dest,chanrec* channel); + + /** Called after a user has been successfully invited to a channel. + * You cannot prevent the invite from occuring using this function, to do that, + * use OnUserPreInvite instead. + * @param source The user who is issuing the INVITE + * @param dest The user being invited + * @param channel The channel the user is being invited to + */ + virtual void OnUserInvite(userrec* source,userrec* dest,chanrec* channel); + + /** Called whenever a user is about to PRIVMSG A user or a channel, before any processing is done. + * Returning any nonzero value 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. This is useful for modules which may want to filter or redirect messages. + * target_type can be one of TYPE_USER or TYPE_CHANNEL. If the target_type value is a user, + * you must cast dest to a userrec* otherwise you must cast it to a chanrec*, this is the details + * of where the message is destined to be sent. + * @param user The user sending the message + * @param dest The target of the message (chanrec* or userrec*) + * @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, 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 + * output to be sent to the user by the core. If you do this you must produce your own numerics, + * notices etc. This is useful for modules which may want to filter or redirect messages. + * target_type can be one of TYPE_USER or TYPE_CHANNEL. If the target_type value is a user, + * you must cast dest to a userrec* otherwise you must cast it to a chanrec*, this is the details + * of where the message is destined to be sent. + * You may alter the message text as you wish before relinquishing control to the next module + * in the chain, and if no other modules block the text this altered form of the text will be sent out + * to the user and possibly to other servers. + * @param user The user sending the message + * @param dest The target of the message (chanrec* or userrec*) + * @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, 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 + * NOT make any changes to the userrec if the user is a remote user as this may cause a desnyc. + * check user->server before taking any action (including returning nonzero from the method). + * If your method returns nonzero, the nickchange is silently forbidden, and it is down to your + * module to generate some meaninful output. + * @param user The username changing their nick + * @param newnick Their new nickname + * @return 1 to deny the change, 0 to allow + */ + virtual int OnUserPreNick(userrec* user, const std::string &newnick); + + /** Called after any PRIVMSG sent from a user. + * The dest variable contains a userrec* if target_type is TYPE_USER and a chanrec* + * if target_type is TYPE_CHANNEL. + * @param user The user sending the message + * @param dest The target of the message + * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL) + * @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, 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* + * if target_type is TYPE_CHANNEL. + * @param user The user sending the message + * @param dest The target of the message + * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL) + * @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, 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* + * if target_type is TYPE_CHANNEL. The text variable contains the remainder of the + * mode string after the target, e.g. "+wsi" or "+ooo nick1 nick2 nick3". + * @param user The user sending the MODEs + * @param dest The target of the modes (userrec* or chanrec*) + * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL) + * @param text The actual modes and their parameters if any + */ + virtual void OnMode(userrec* user, void* dest, int target_type, const std::string &text); + + /** Allows modules to alter or create server descriptions + * Whenever a module requires a server description, for example for display in + * WHOIS, this function is called in all modules. You may change or define the + * description given in std::string &description. If you do, this description + * will be shown in the WHOIS fields. + * @param servername The servername being searched for + * @param description Alterable server description for this server + */ + virtual void OnGetServerDescription(const std::string &servername,std::string &description); + + /** Allows modules to synchronize data which relates to users during a netburst. + * When this function is called, it will be called from the module which implements + * 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! + * @param user The user 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! + */ + virtual void OnSyncUser(userrec* user, Module* proto, void* opaque); + + /** Allows modules to synchronize data which relates to channels during a netburst. + * When this function is called, it will be called from the module which implements + * 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! + * + * For a good example of how to use this function, please see src/modules/m_chanprotect.cpp + * + * @param chan The channel 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! + */ + virtual void OnSyncChannel(chanrec* 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 userrec or chanrec 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(chanrec* 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 userrec or chanrec 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(userrec* 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 userrec or chanrec 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 proto A pointer to the module handling network protocol + * @param opaque An opaque pointer set by the protocol module, should not be modified! + * @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); + + /** 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. + * @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL + * @param target The chanrec* or userrec* that data should be added to + * @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); + + /** Implemented by modules which provide the ability to link servers. + * These modules will implement this method, which allows transparent sending of servermodes + * down the network link as a broadcast, without a module calling it having to know the format + * of the MODE command before the actual mode string. + * + * More documentation to follow soon. Please see src/modules/m_chanprotect.cpp for examples + * of how to use this function. + * + * @param opaque An opaque pointer set by the protocol module, should not be modified! + * @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL + * @param target The chanrec* or userrec* that modes should be sent for + * @param modeline The modes and parameters to be sent + */ + virtual void ProtoSendMode(void* opaque, int target_type, void* target, const std::string &modeline); + + /** Implemented by modules which provide the ability to link servers. + * These modules will implement this method, which allows metadata (extra data added to + * user and channel records using class Extensible, Extensible::Extend, etc) to be sent + * to other servers on a netburst and decoded at the other end by the same module on a + * different server. + * + * More documentation to follow soon. Please see src/modules/m_swhois.cpp for example of + * how to use this function. + * @param opaque An opaque pointer set by the protocol module, should not be modified! + * @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL + * @param target The chanrec* or userrec* that metadata should be sent for + * @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, int target_type, void* target, const std::string &extname, const std::string &extdata); + + /** Called after every WALLOPS command. + * @param user The user sending the WALLOPS + * @param text The content of the WALLOPS message + */ + virtual void OnWallops(userrec* user, const std::string &text); + + /** Called whenever a user's hostname is changed. + * This event triggers after the host has been set. + * @param user The user whos host is being changed + * @param newhost The new hostname being set + */ + virtual void OnChangeHost(userrec* user, const std::string &newhost); + + /** Called whenever a user's GECOS (realname) is changed. + * This event triggers after the name has been set. + * @param user The user who's GECOS is being changed + * @param gecos The new GECOS being set on the user + */ + virtual void OnChangeName(userrec* user, const std::string &gecos); + + /** Called whenever a gline is added by a local user. + * This method is triggered after the line is added. + * @param duration The duration of the line in seconds + * @param source The sender of the line + * @param reason The reason text to be displayed + * @param hostmask The hostmask to add + */ + virtual void OnAddGLine(long duration, userrec* source, const std::string &reason, const std::string &hostmask); + + /** Called whenever a zline is added by a local user. + * This method is triggered after the line is added. + * @param duration The duration of the line in seconds + * @param source The sender of the line + * @param reason The reason text to be displayed + * @param ipmask The hostmask to add + */ + virtual void OnAddZLine(long duration, userrec* source, const std::string &reason, const std::string &ipmask); + + /** Called whenever a kline is added by a local user. + * This method is triggered after the line is added. + * @param duration The duration of the line in seconds + * @param source The sender of the line + * @param reason The reason text to be displayed + * @param hostmask The hostmask to add + */ + virtual void OnAddKLine(long duration, userrec* source, const std::string &reason, const std::string &hostmask); + + /** Called whenever a qline is added by a local user. + * This method is triggered after the line is added. + * @param duration The duration of the line in seconds + * @param source The sender of the line + * @param reason The reason text to be displayed + * @param nickmask The hostmask to add + */ + virtual void OnAddQLine(long duration, userrec* source, const std::string &reason, const std::string &nickmask); + + /** Called whenever a eline is added by a local user. + * This method is triggered after the line is added. + * @param duration The duration of the line in seconds + * @param source The sender of the line + * @param reason The reason text to be displayed + * @param hostmask The hostmask to add + */ + virtual void OnAddELine(long duration, userrec* source, const std::string &reason, const std::string &hostmask); + + /** Called whenever a gline is deleted. + * This method is triggered after the line is deleted. + * @param source The user removing the line + * @param hostmask The hostmask to delete + */ + virtual void OnDelGLine(userrec* source, const std::string &hostmask); + + /** Called whenever a zline is deleted. + * This method is triggered after the line is deleted. + * @param source The user removing the line + * @param hostmask The hostmask to delete + */ + virtual void OnDelZLine(userrec* source, const std::string &ipmask); + + /** Called whenever a kline is deleted. + * This method is triggered after the line is deleted. + * @param source The user removing the line + * @param hostmask The hostmask to delete + */ + virtual void OnDelKLine(userrec* source, const std::string &hostmask); + + /** Called whenever a qline is deleted. + * This method is triggered after the line is deleted. + * @param source The user removing the line + * @param hostmask The hostmask to delete + */ + virtual void OnDelQLine(userrec* source, const std::string &nickmask); + + /** Called whenever a eline is deleted. + * This method is triggered after the line is deleted. + * @param source The user removing the line + * @param hostmask The hostmask to delete + */ + virtual void OnDelELine(userrec* source, const std::string &hostmask); + + /** Called before your module is unloaded to clean up Extensibles. + * This method is called once for every user and channel on the network, + * so that when your module unloads it may clear up any remaining data + * in the form of Extensibles added using Extensible::Extend(). + * If the target_type variable is TYPE_USER, then void* item refers to + * a userrec*, otherwise it refers to a chanrec*. + * @param target_type The type of item being cleaned + * @param item A pointer to the item's class + */ + virtual void OnCleanup(int target_type, void* item); + + /** Called after any nickchange, local or remote. This can be used to track users after nickchanges + * have been applied. Please note that although you can see remote nickchanges through this function, you should + * NOT make any changes to the userrec if the user is a remote user as this may cause a desnyc. + * check user->server before taking any action (including returning nonzero from the method). + * Because this method is called after the nickchange is taken place, no return values are possible + * to indicate forbidding of the nick change. Use OnUserPreNick for this. + * @param user The user changing their nick + * @param oldnick The old nickname of the user before the nickchange + */ + virtual void OnUserPostNick(userrec* user, const std::string &oldnick); + + /** Called before an action which requires a channel privilage check. + * This function is called before many functions which check a users status on a channel, for example + * before opping a user, deopping a user, kicking a user, etc. + * There are several values for access_type which indicate for what reason access is being checked. + * These are:<br><br> + * AC_KICK (0) - A user is being kicked<br> + * AC_DEOP (1) - a user is being deopped<br> + * AC_OP (2) - a user is being opped<br> + * AC_VOICE (3) - a user is being voiced<br> + * AC_DEVOICE (4) - a user is being devoiced<br> + * AC_HALFOP (5) - a user is being halfopped<br> + * AC_DEHALFOP (6) - a user is being dehalfopped<br> + * AC_INVITE () - a user is being invited<br> + * AC_GENERAL_MODE (8) - a user channel mode is being changed<br><br> + * Upon returning from your function you must return either ACR_DEFAULT, to indicate the module wishes + * to do nothing, or ACR_DENY where approprate to deny the action, and ACR_ALLOW where appropriate to allow + * the action. Please note that in the case of some access checks (such as AC_GENERAL_MODE) access may be + * denied 'upstream' causing other checks such as AC_DEOP to not be reached. Be very careful with use of the + * AC_GENERAL_MODE type, as it may inadvertently override the behaviour of other modules. When the access_type + * is AC_GENERAL_MODE, the destination of the mode will be NULL (as it has not yet been determined). + * @param source The source of the access check + * @param dest The destination of the access check + * @param channel The channel which is being checked + * @param access_type See above + */ + virtual int OnAccessCheck(userrec* source,userrec* dest,chanrec* channel,int access_type); + + /** Called when a 005 numeric is about to be output. + * The module should modify the 005 numeric if needed to indicate its features. + * @param output The 005 string to be modified if neccessary. + */ + virtual void On005Numeric(std::string &output); + + /** Called when a client is disconnected by KILL. + * If a client is killed by a server, e.g. a nickname collision or protocol error, + * source is NULL. + * Return 1 from this function to prevent the kill, and 0 from this function to allow + * it as normal. If you prevent the kill no output will be sent to the client, it is + * down to your module to generate this information. + * NOTE: It is NOT advisable to stop kills which originate from servers or remote users. + * If you do so youre risking race conditions, desyncs and worse! + * @param source The user sending the KILL + * @param dest The user being killed + * @param reason The kill reason + * @return 1 to prevent the kill, 0 to allow + */ + virtual int OnKill(userrec* source, userrec* dest, const std::string &reason); + + /** Called when an oper wants to disconnect a remote user via KILL + * @param source The user sending the KILL + * @param dest The user being killed + * @param reason The kill reason + */ + virtual void OnRemoteKill(userrec* source, userrec* dest, const std::string &reason, const std::string &operreason); + + /** Called whenever a module is loaded. + * mod will contain a pointer to the module, and string will contain its name, + * for example m_widgets.so. This function is primary for dependency checking, + * your module may decide to enable some extra features if it sees that you have + * for example loaded "m_killwidgets.so" with "m_makewidgets.so". It is highly + * recommended that modules do *NOT* bail if they cannot satisfy dependencies, + * but instead operate under reduced functionality, unless the dependency is + * absolutely neccessary (e.g. a module that extends the features of another + * module). + * @param mod A pointer to the new module + * @param name The new module's filename + */ + virtual void OnLoadModule(Module* mod,const std::string &name); + + /** Called whenever a module is unloaded. + * mod will contain a pointer to the module, and string will contain its name, + * for example m_widgets.so. This function is primary for dependency checking, + * your module may decide to enable some extra features if it sees that you have + * for example loaded "m_killwidgets.so" with "m_makewidgets.so". It is highly + * recommended that modules do *NOT* bail if they cannot satisfy dependencies, + * but instead operate under reduced functionality, unless the dependency is + * absolutely neccessary (e.g. a module that extends the features of another + * module). + * @param mod Pointer to the module being unloaded (still valid) + * @param name The filename of the module being unloaded + */ + virtual void OnUnloadModule(Module* mod,const 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. + * @param curtime The current timer derived from time(2) + */ + virtual void OnBackgroundTimer(time_t curtime); + + /** 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, and for invalid commands. Invalid commands may only be sent to this + * function when the value of validated is false. 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 + * InspIRCd::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!) + * @param command The command being executed + * @param parameters An array of array of characters containing the parameters for the command + * @param pcnt The nuimber of parameters passed to the command + * @param user the user issuing the command + * @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. + * @param original_line The entire original line as passed to the parser from the user + * @return 1 to block the command, 0 to allow + */ + virtual int OnPreCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, bool validated, const std::string &original_line); + + /** Called after any command has been 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). The result code returned by the command handler is + * provided. + * @param command The command being executed + * @param parameters An array of array of characters containing the parameters for the command + * @param pcnt The nuimber of parameters passed to the command + * @param user the user issuing the command + * @param result The return code given by the command handler, one of CMD_SUCCESS or CMD_FAILURE + * @param original_line The entire original line as passed to the parser from the user + */ + virtual void OnPostCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, CmdResult result, const std::string &original_line); + + /** 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. + * @param user The user to check + * @return true to indicate readiness, false if otherwise + */ + 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. + * @param user The user registering + * @return 1 to indicate user quit, 0 to continue + */ + 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 + * 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. + * @param user The user joining the channel + * @param chan The channel being joined + * @return 1 to explicitly allow the join, 0 to proceed as normal + */ + 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. + * @param user The user joining the channel + * @param chan The channel being joined + * @return 1 to explicitly allow the join, 0 to proceed as normal + */ + virtual int OnCheckKey(userrec* user, chanrec* chan, const 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. + * @param user The user joining the channel + * @param chan The channel being joined + * @return 1 to explicitly allow the join, 0 to proceed as normal + */ + 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. + * @param user The user joining the channel + * @param chan The channel being joined + * @return 1 to explicitly allow the join, 0 to proceed as normal + */ + 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. + * @param symbol the symbol provided to /STATS + * @param user the user issuing the /STATS command + * @param results A string_list to append results into. You should put all your results + * into this string_list, rather than displaying them directly, so that your handler will + * work when remote STATS queries are received. + * @return 1 to block the /STATS from being processed by the core, 0 to allow it + */ + virtual int OnStats(char symbol, userrec* user, string_list &results); + + /** Called whenever a change of a local users displayed host is attempted. + * Return 1 to deny the host change, or 0 to allow it. + * @param user The user whos host will be changed + * @param newhost The new hostname + * @return 1 to deny the host change, 0 to allow + */ + virtual int OnChangeLocalUserHost(userrec* user, const 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. + * @param user The user whos GECOS will be changed + * @param newhost The new GECOS + * @return 1 to deny the GECOS change, 0 to allow + */ + virtual int OnChangeLocalUserGECOS(userrec* user, const 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. + * @param user The user changing the topic + * @param chan The channels who's topic is being changed + * @param topic The actual topic text + * @param 1 to block the topic change, 0 to allow + */ + virtual int OnLocalTopicChange(userrec* user, chanrec* chan, const std::string &topic); + + /** Called whenever a local topic has been changed. + * To block topic changes you must use OnLocalTopicChange instead. + * @param user The user changing the topic + * @param chan The channels who's topic is being changed + * @param topic The actual topic text + */ + virtual void OnPostLocalTopicChange(userrec* user, chanrec* chan, const std::string &topic); + + /** 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! + * @param event The Event class being received + */ + 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). + * @param request The Request class being received + */ + virtual char* OnRequest(Request* request); + + /** Called whenever an oper password is to be compared to what a user has input. + * The password field (from the config file) is in 'password' and is to be compared against + * 'input'. This method allows for encryption of oper passwords and much more besides. + * You should return a nonzero value if you want to allow the comparison or zero if you wish + * to do nothing. + * @param password The oper's password + * @param input The password entered + * @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, 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 + * such a task must be performed by another server. You can however bounce modes by sending + * servermodes out to reverse mode changes. + * @param user The user who is opering + */ + virtual void OnGlobalOper(userrec* user); + + /** Called after a user has fully connected and all modules have executed OnUserConnect + * This event is informational only. You should not change any user information in this + * event. To do so, use the OnUserConnect method to change the state of local users. + * This is called for both local and remote users. + * @param user The user who is connecting + */ + virtual void OnPostConnect(userrec* user); + + /** Called whenever a ban is added to a channel's list. + * Return a non-zero value to 'eat' the mode change and prevent the ban from being added. + * @param source The user adding the ban + * @param channel The channel the ban is being added to + * @param banmask The ban mask being added + * @return 1 to block the ban, 0 to continue as normal + */ + virtual int OnAddBan(userrec* source, chanrec* channel,const std::string &banmask); + + /** Called whenever a ban is removed from a channel's list. + * Return a non-zero value to 'eat' the mode change and prevent the ban from being removed. + * @param source The user deleting the ban + * @param channel The channel the ban is being deleted from + * @param banmask The ban mask being deleted + * @return 1 to block the unban, 0 to continue as normal + */ + virtual int OnDelBan(userrec* source, chanrec* channel,const std::string &banmask); + + /** 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 + * no information relating to a user record as the connection has not been assigned yet. + * 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 localport The local port number the user connected to + */ + virtual void OnRawSocketAccept(int fd, const std::string &ip, int localport); + + /** 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 + * for use by modules which may wrap connections within another API such as SSL for example. + * return a non-zero result if you have handled the write operation, in which case the core + * will not call write(). + * @param fd The file descriptor of the socket + * @param buffer A char* buffer being written + * @param Number of characters to write + * @return Number of characters actually written or 0 if you didn't handle the operation + */ + virtual int OnRawSocketWrite(int fd, const char* buffer, int count); + + /** Called immediately before any socket is closed. When this event is called, shutdown() + * has not yet been called on the socket. + * @param fd The file descriptor of the socket prior to close() + */ + virtual void OnRawSocketClose(int fd); + + /** Called immediately upon connection of an outbound InspSocket which has been hooked + * by a module. + * @param fd The file descriptor of the socket immediately after connect() + */ + 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. + * Your event should return 1 if it has handled the reading itself, which prevents the core + * just using read(). You should place any data read into buffer, up to but NOT GREATER THAN + * the value of count. The value of readresult must be identical to an actual result that might + * be returned from the read() system call, for example, number of bytes read upon success, + * 0 upon EOF or closed socket, and -1 for error. If your function returns a nonzero value, + * you MUST set readresult. + * @param fd The file descriptor of the socket + * @param buffer A char* buffer being read to + * @param count The size of the buffer + * @param readresult The amount of characters read, or 0 + * @return nonzero if the event was handled, in which case readresult must be valid on exit + */ + virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult); + + /** Called whenever a user sets away. + * This method has no parameter for the away message, as it is available in the + * user record as userrec::awaymsg. + * @param user The user setting away + */ + virtual void OnSetAway(userrec* user); + + /** Called when a user cancels their away state. + * @param user The user returning from away + */ + virtual void OnCancelAway(userrec* user); + + /** Called whenever a NAMES list is requested. + * You can produce the nameslist yourself, overriding the current list, + * and if you do you must return 1. If you do not handle the names list, + * return 0. + * @param The user requesting the NAMES list + * @param Ptr The channel the NAMES list is requested for + * @param userlist The user list for the channel (you may change this pointer. + * If you want to change the values, take a copy first, and change the copy, then + * point the pointer at your copy) + * @return 1 to prevent the user list being sent to the client, 0 to allow it + */ + virtual int OnUserList(userrec* user, chanrec* Ptr, CUList* &userlist); + + /** 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(); + + /** Called whenever a user's write buffer has been completely sent. + * This is called when the user's write buffer is completely empty, and + * there are no more pending bytes to be written and no pending write events + * in the socket engine's queue. This may be used to refill the buffer with + * data which is being spooled in a controlled manner, e.g. LIST lines. + * @param user The user who's buffer is now empty. + */ + virtual void OnBufferFlushed(userrec* user); +}; + + +#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. + * Constructing the class using one parameter allows you to specify a path to your own configuration + * file, otherwise, inspircd.conf is read. + */ +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; + + public: + /** Default constructor. + * This constructor initialises the ConfigReader class to read the inspircd.conf file + * 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. + */ + ~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, 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 + * 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 + */ + 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. + */ + long GetError(); + /** Counts the number of times a given tag appears in the config file. + * This method counts the number of times a tag appears in a config file, for use where + * there are several tags of the same kind, e.g. with opers and connect types. It can be + * used with the index value of ConfigReader::ReadValue to loop through all copies of a + * 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,userrec* user); + + /** Returns the number of items within a tag. + * For example if the tag was <test tag="blah" data="foo"> then this + * function would return 2. Spaces and newlines both qualify as valid seperators + * between values. + */ + int EnumerateValues(const std::string &tag, int index); +}; + + + +/** Caches a text file into memory and can be used to retrieve lines from it. + * This class contains methods for read-only manipulation of a text file in memory. + * Either use the constructor type with one parameter to load a file into memory + * at construction, or use the LoadFile method to load a file. + */ +class CoreExport FileReader : public classbase +{ + InspIRCd* ServerInstance; + /** The file contents + */ + file_cache fc; + + /** Content size in bytes + */ + unsigned long contentsize; + + /** Calculate content size in bytes + */ + void CalcSize(); + + public: + /** Default constructor. + * This method does not load any file into memory, you must use the LoadFile method + * after constructing the class this way. + */ + FileReader(InspIRCd* Instance); + + /** Secondary constructor. + * This method initialises the class with a file loaded into it ready for GetLine and + * and other methods to be called. If the file could not be loaded, FileReader::FileSize + * returns 0. + */ + FileReader(InspIRCd* Instance, const std::string &filename); + + /** Default destructor. + * This deletes the memory allocated to the file. + */ + ~FileReader(); + + /** Used to load a file. + * This method loads a file into the class ready for GetLine and + * and other methods to be called. If the file could not be loaded, FileReader::FileSize + * returns 0. + */ + void LoadFile(const std::string &filename); + + /** Returns the whole content of the file as std::string + */ + std::string Contents(); + + /** Returns the entire size of the file as std::string + */ + unsigned long ContentSize(); + + /** Returns true if the file exists + * This function will return false if the file could not be opened. + */ + bool Exists(); + + /** Retrieve one line from the file. + * This method retrieves one line from the text file. If an empty non-NULL string is returned, + * the index was out of bounds, or the line had no data on it. + */ + std::string GetLine(int x); + + /** Returns the size of the file in lines. + * This method returns the number of lines in the read file. If it is 0, no lines have been + * read into memory, either because the file is empty or it does not exist, or cannot be + * opened due to permission problems. + */ + int FileSize(); +}; + + +/** Instantiates classes inherited from Module. + * This class creates a class inherited from type Module, using new. This is to allow for modules + * to create many different variants of Module, dependent on architecture, configuration, etc. + * In most cases, the simple class shown in the example module m_foobar.so will suffice for most + * modules. + */ +class CoreExport ModuleFactory : public classbase +{ + public: + /** The default constructor does nothing. + */ + ModuleFactory() { } + /** The default destructor does nothing + */ + virtual ~ModuleFactory() { } + /** Creates a new module. + * Your inherited class of ModuleFactory must return a pointer to your Module class + * using this method. + */ + virtual Module * CreateModule(InspIRCd* Me) = 0; +}; + +/** A DLLFactory (designed to load shared objects) containing a ModuleFactory. + */ +typedef DLLFactory<ModuleFactory> ircd_module; + +/** A list of loaded Modules + */ +typedef std::vector<Module*> ModuleList; + +/** A list of loaded ModuleFactories + */ +typedef std::vector<ircd_module*> FactoryList; + +/** This definition is used as shorthand for the various classes + * and functions needed to make a module loadable by the OS. + * It defines the class factory and external init_module function. + */ +#define MODULE_INIT(y) \ + class Factory : public ModuleFactory \ + { \ + public: \ + virtual Module * CreateModule(InspIRCd* Me) \ + { \ + return new y(Me); \ + } \ + }; \ + extern "C" DllExport void * init_module(void) \ + { \ + return new Factory; \ + } + +#endif + diff --git a/include/snomasks.h b/include/snomasks.h index b318fdc26..db8be55f8 100644 --- a/include/snomasks.h +++ b/include/snomasks.h @@ -1 +1,85 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __SNOMASKS_H__
#define __SNOMASKS_H__
#include <string>
#include <vector>
#include <map>
#include "configreader.h"
#include "inspircd.h"
/** A list of snomasks which are valid, and their descriptive texts
*/
typedef std::map<char, std::string> SnoList;
/** Snomask manager handles routing of SNOMASK (usermode +n) messages to opers.
* Modules and the core can enable and disable snomask characters. If they do,
* then sending snomasks using these characters becomes possible.
*/
class CoreExport SnomaskManager : public Extensible
{
private:
/** Creator/owner
*/
InspIRCd* ServerInstance;
/** Currently active snomask list
*/
SnoList SnoMasks;
/** Set up the default (core available) snomask chars
*/
void SetupDefaults();
public:
/** Create a new SnomaskManager
*/
SnomaskManager(InspIRCd* Instance);
/** Delete SnomaskManager
*/
~SnomaskManager();
/** Enable a snomask.
* @param letter The snomask letter to enable. Once enabled,
* server notices may be routed to users with this letter in
* their list, and users may add this letter to their list.
* @param description The descriptive text sent along with any
* server notices, at the start of the notice, e.g. "GLOBOPS".
* @return True if the snomask was enabled, false if it already
* exists.
*/
bool EnableSnomask(char letter, const std::string &description);
/** Disable a snomask.
* @param letter The snomask letter to disable.
* @return True if the snomask was disabled, false if it didn't
* exist.
*/
bool DisableSnomask(char letter);
/** Write to all users with a given snomask.
* @param letter The snomask letter to write to
* @param text The text to send to the users
*/
void WriteToSnoMask(char letter, const std::string &text);
/** Write to all users with a given snomask.
* @param letter The snomask letter to write to
* @param text A format string containing text to send
* @param ... Format arguments
*/
void WriteToSnoMask(char letter, const char* text, ...);
/** Check if a snomask is enabled.
* @param letter The snomask letter to check.
* @return True if the snomask has been enabled.
*/
bool IsEnabled(char letter);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __SNOMASKS_H__ +#define __SNOMASKS_H__ + +#include <string> +#include <vector> +#include <map> +#include "configreader.h" +#include "inspircd.h" + +/** A list of snomasks which are valid, and their descriptive texts + */ +typedef std::map<char, std::string> SnoList; + +/** Snomask manager handles routing of SNOMASK (usermode +n) messages to opers. + * Modules and the core can enable and disable snomask characters. If they do, + * then sending snomasks using these characters becomes possible. + */ +class CoreExport SnomaskManager : public Extensible +{ + private: + /** Creator/owner + */ + InspIRCd* ServerInstance; + /** Currently active snomask list + */ + SnoList SnoMasks; + /** Set up the default (core available) snomask chars + */ + void SetupDefaults(); + public: + /** Create a new SnomaskManager + */ + SnomaskManager(InspIRCd* Instance); + /** Delete SnomaskManager + */ + ~SnomaskManager(); + + /** Enable a snomask. + * @param letter The snomask letter to enable. Once enabled, + * server notices may be routed to users with this letter in + * their list, and users may add this letter to their list. + * @param description The descriptive text sent along with any + * server notices, at the start of the notice, e.g. "GLOBOPS". + * @return True if the snomask was enabled, false if it already + * exists. + */ + bool EnableSnomask(char letter, const std::string &description); + /** Disable a snomask. + * @param letter The snomask letter to disable. + * @return True if the snomask was disabled, false if it didn't + * exist. + */ + bool DisableSnomask(char letter); + /** Write to all users with a given snomask. + * @param letter The snomask letter to write to + * @param text The text to send to the users + */ + void WriteToSnoMask(char letter, const std::string &text); + /** Write to all users with a given snomask. + * @param letter The snomask letter to write to + * @param text A format string containing text to send + * @param ... Format arguments + */ + void WriteToSnoMask(char letter, const char* text, ...); + /** Check if a snomask is enabled. + * @param letter The snomask letter to check. + * @return True if the snomask has been enabled. + */ + bool IsEnabled(char letter); +}; + +#endif diff --git a/include/socket.h b/include/socket.h index 458cbe690..57725b95f 100644 --- a/include/socket.h +++ b/include/socket.h @@ -1 +1,225 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef INSPIRCD_SOCKET_H
#define INSPIRCD_SOCKET_H
#ifndef WIN32
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#else
#include "inspircd_win32wrapper.h"
#endif
#include <errno.h>
#include "inspircd_config.h"
#include "socketengine.h"
/* Accept Define */
#ifdef CONFIG_USE_IOCP
/* IOCP wrapper for accept() */
#define _accept(s, addr, addrlen) __accept_socket(s, addr, addrlen, m_acceptEvent)
/* IOCP wrapper for getsockname() */
#define _getsockname(fd, sockptr, socklen) __getsockname(fd, sockptr, socklen, m_acceptEvent)
/* IOCP wrapper for recvfrom() */
#define _recvfrom(s, buf, len, flags, from, fromlen) __recvfrom(s, buf, len, flags, from, fromlen, ((IOCPEngine*)ServerInstance->SE)->udp_ov)
#else
/* No wrapper for recvfrom() */
#define _recvfrom recvfrom
/* No wrapper for accept() */
#define _accept accept
/* No wrapper for getsockname() */
#define _getsockname getsockname
#endif
/* Contains irc-specific definitions */
namespace irc
{
/** This namespace contains various protocol-independent helper classes.
* It also contains some types which are often used by the core and modules
* in place of inet_* functions and types.
*/
namespace sockets
{
/* macros to the relevant system address description structs */
#ifdef IPV6
/** insp_sockaddr for ipv6
*/
typedef struct sockaddr_in6 insp_sockaddr;
/** insp_inaddr for ipv6
*/
typedef struct in6_addr insp_inaddr;
#define AF_FAMILY AF_INET6
#define PF_PROTOCOL PF_INET6
#else
/** insp_sockaddr for ipv4
*/
typedef struct sockaddr_in insp_sockaddr;
/** insp_inaddr for ipv4
*/
typedef struct in_addr insp_inaddr;
#define AF_FAMILY AF_INET
#define PF_PROTOCOL PF_INET
#endif
/** Match raw binary data using CIDR rules.
*
* This function will use binary comparison to compare the
* two bit sequences, address and mask, up to mask_bits
* bits in size. If they match, it will return true.
* @param address The whole address, of 4 or 16 bytes in length
* @param mask The mask, from 1 to 16 bytes in length, anything
* from 1 to 128 bits of which is significant
* @param mask_Bits How many bits of the mask parameter are significant
* for this comparison.
* @returns True if the first mask_bits of address matches the first
* mask_bits of mask.
*/
CoreExport bool MatchCIDRBits(unsigned char* address, unsigned char* mask, unsigned int mask_bits);
/** Match CIDR, without matching username/nickname parts.
*
* This function will compare a human-readable address against a human-
* readable CIDR mask, for example 1.2.3.4 against 1.2.0.0/16. This
* method supports both IPV4 and IPV6 addresses.
* @param address The human readable address, e.g. 1.2.3.4
* @param cidr_mask The human readable mask, e.g. 1.2.0.0/16
* @return True if the mask matches the address
*/
CoreExport bool MatchCIDR(const char* address, const char* cidr_mask);
/** Match CIDR, including an optional username/nickname part.
*
* This function will compare a human-readable address (plus
* optional username and nickname) against a human-readable
* CIDR mask, for example joe!bloggs\@1.2.3.4 against
* *!bloggs\@1.2.0.0/16. This method supports both IPV4 and
* IPV6 addresses.
* @param address The human readable address, e.g. fred\@1.2.3.4
* @param cidr_mask The human readable mask, e.g. *\@1.2.0.0/16
* @return True if the mask matches the address
*/
CoreExport bool MatchCIDR(const char* address, const char* cidr_mask, bool match_with_username);
/** Convert an insp_inaddr into human readable form.
*
* @param n An insp_inaddr (IP address) structure
* @return A human-readable address. IPV6 addresses
* will be shortened to remove fields which are 0.
*/
CoreExport const char* insp_ntoa(insp_inaddr n);
/** Convert a human-readable address into an insp_inaddr.
*
* @param a A human-readable address
* @param n An insp_inaddr struct which the result
* will be copied into on success.
* @return This method will return a negative value if address
* does not contain a valid address family. 0 if the address is
* does not contain a valid string representing a valid network
* address. A positive value is returned if the network address
* was successfully converted.
* or any other number upon failure.
*/
CoreExport int insp_aton(const char* a, insp_inaddr* n);
/** Make a socket file descriptor a blocking socket
* @param s A valid file descriptor
*/
CoreExport void Blocking(int s);
/** Make a socket file descriptor into a nonblocking socket
* @param s A valid file descriptor
*/
CoreExport void NonBlocking(int s);
/** Create a new valid file descriptor using socket()
* @return On return this function will return a value >= 0 for success,
* or a negative value upon failure (negative values are invalid file
* descriptors)
*/
CoreExport int OpenTCPSocket(char* addr, int socktype = SOCK_STREAM);
}
}
/** This class handles incoming connections on client ports.
* It will create a new userrec for every valid connection
* and assign it a file descriptor.
*/
class CoreExport ListenSocket : public EventHandler
{
protected:
/** The creator/owner of this object
*/
InspIRCd* ServerInstance;
/** Socket description (shown in stats p) */
std::string desc;
/** Socket address family */
int family;
/** Address socket is bound to */
std::string bind_addr;
/** Port socket is bound to */
int bind_port;
public:
/** Create a new listening socket
*/
ListenSocket(InspIRCd* Instance, int port, char* addr);
/** Handle an I/O event
*/
void HandleEvent(EventType et, int errornum = 0);
/** Close the socket
*/
~ListenSocket();
/** Set descriptive text
*/
void SetDescription(const std::string &description)
{
desc = description;
}
/** Get description for socket
*/
const std::string& GetDescription()
{
return desc;
}
/** Get port number for socket
*/
int GetPort()
{
return bind_port;
}
/** Get IP address socket is bound to
*/
std::string &GetIP()
{
return bind_addr;
}
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef INSPIRCD_SOCKET_H +#define INSPIRCD_SOCKET_H + +#ifndef WIN32 + +#include <arpa/inet.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <unistd.h> +#include <fcntl.h> +#include <netdb.h> + +#else + +#include "inspircd_win32wrapper.h" + +#endif + +#include <errno.h> +#include "inspircd_config.h" +#include "socketengine.h" + +/* Accept Define */ +#ifdef CONFIG_USE_IOCP +/* IOCP wrapper for accept() */ +#define _accept(s, addr, addrlen) __accept_socket(s, addr, addrlen, m_acceptEvent) +/* IOCP wrapper for getsockname() */ +#define _getsockname(fd, sockptr, socklen) __getsockname(fd, sockptr, socklen, m_acceptEvent) +/* IOCP wrapper for recvfrom() */ +#define _recvfrom(s, buf, len, flags, from, fromlen) __recvfrom(s, buf, len, flags, from, fromlen, ((IOCPEngine*)ServerInstance->SE)->udp_ov) +#else +/* No wrapper for recvfrom() */ +#define _recvfrom recvfrom +/* No wrapper for accept() */ +#define _accept accept +/* No wrapper for getsockname() */ +#define _getsockname getsockname +#endif + +/* Contains irc-specific definitions */ +namespace irc +{ + /** This namespace contains various protocol-independent helper classes. + * It also contains some types which are often used by the core and modules + * in place of inet_* functions and types. + */ + namespace sockets + { + + /* macros to the relevant system address description structs */ +#ifdef IPV6 + /** insp_sockaddr for ipv6 + */ + typedef struct sockaddr_in6 insp_sockaddr; + /** insp_inaddr for ipv6 + */ + typedef struct in6_addr insp_inaddr; +#define AF_FAMILY AF_INET6 +#define PF_PROTOCOL PF_INET6 + +#else + /** insp_sockaddr for ipv4 + */ + typedef struct sockaddr_in insp_sockaddr; + /** insp_inaddr for ipv4 + */ + typedef struct in_addr insp_inaddr; +#define AF_FAMILY AF_INET +#define PF_PROTOCOL PF_INET + +#endif + /** Match raw binary data using CIDR rules. + * + * This function will use binary comparison to compare the + * two bit sequences, address and mask, up to mask_bits + * bits in size. If they match, it will return true. + * @param address The whole address, of 4 or 16 bytes in length + * @param mask The mask, from 1 to 16 bytes in length, anything + * from 1 to 128 bits of which is significant + * @param mask_Bits How many bits of the mask parameter are significant + * for this comparison. + * @returns True if the first mask_bits of address matches the first + * mask_bits of mask. + */ + CoreExport bool MatchCIDRBits(unsigned char* address, unsigned char* mask, unsigned int mask_bits); + + /** Match CIDR, without matching username/nickname parts. + * + * This function will compare a human-readable address against a human- + * readable CIDR mask, for example 1.2.3.4 against 1.2.0.0/16. This + * method supports both IPV4 and IPV6 addresses. + * @param address The human readable address, e.g. 1.2.3.4 + * @param cidr_mask The human readable mask, e.g. 1.2.0.0/16 + * @return True if the mask matches the address + */ + CoreExport bool MatchCIDR(const char* address, const char* cidr_mask); + + /** Match CIDR, including an optional username/nickname part. + * + * This function will compare a human-readable address (plus + * optional username and nickname) against a human-readable + * CIDR mask, for example joe!bloggs\@1.2.3.4 against + * *!bloggs\@1.2.0.0/16. This method supports both IPV4 and + * IPV6 addresses. + * @param address The human readable address, e.g. fred\@1.2.3.4 + * @param cidr_mask The human readable mask, e.g. *\@1.2.0.0/16 + * @return True if the mask matches the address + */ + CoreExport bool MatchCIDR(const char* address, const char* cidr_mask, bool match_with_username); + + /** Convert an insp_inaddr into human readable form. + * + * @param n An insp_inaddr (IP address) structure + * @return A human-readable address. IPV6 addresses + * will be shortened to remove fields which are 0. + */ + CoreExport const char* insp_ntoa(insp_inaddr n); + + /** Convert a human-readable address into an insp_inaddr. + * + * @param a A human-readable address + * @param n An insp_inaddr struct which the result + * will be copied into on success. + * @return This method will return a negative value if address + * does not contain a valid address family. 0 if the address is + * does not contain a valid string representing a valid network + * address. A positive value is returned if the network address + * was successfully converted. + + * or any other number upon failure. + */ + CoreExport int insp_aton(const char* a, insp_inaddr* n); + + /** Make a socket file descriptor a blocking socket + * @param s A valid file descriptor + */ + CoreExport void Blocking(int s); + + /** Make a socket file descriptor into a nonblocking socket + * @param s A valid file descriptor + */ + CoreExport void NonBlocking(int s); + + /** Create a new valid file descriptor using socket() + * @return On return this function will return a value >= 0 for success, + * or a negative value upon failure (negative values are invalid file + * descriptors) + */ + CoreExport int OpenTCPSocket(char* addr, int socktype = SOCK_STREAM); + } +} + +/** This class handles incoming connections on client ports. + * It will create a new userrec for every valid connection + * and assign it a file descriptor. + */ +class CoreExport ListenSocket : public EventHandler +{ + protected: + /** The creator/owner of this object + */ + InspIRCd* ServerInstance; + /** Socket description (shown in stats p) */ + std::string desc; + /** Socket address family */ + int family; + /** Address socket is bound to */ + std::string bind_addr; + /** Port socket is bound to */ + int bind_port; + public: + /** Create a new listening socket + */ + ListenSocket(InspIRCd* Instance, int port, char* addr); + /** Handle an I/O event + */ + void HandleEvent(EventType et, int errornum = 0); + /** Close the socket + */ + ~ListenSocket(); + /** Set descriptive text + */ + void SetDescription(const std::string &description) + { + desc = description; + } + /** Get description for socket + */ + const std::string& GetDescription() + { + return desc; + } + /** Get port number for socket + */ + int GetPort() + { + return bind_port; + } + /** Get IP address socket is bound to + */ + std::string &GetIP() + { + return bind_addr; + } +}; + +#endif + diff --git a/include/socketengine.h b/include/socketengine.h index e34aa3941..ce701beff 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -1 +1,296 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __SOCKETENGINE__
#define __SOCKETENGINE__
#include <vector>
#include <string>
#include <map>
#include "inspircd_config.h"
#include "base.h"
/** Types of event an EventHandler may receive.
* EVENT_READ is a readable file descriptor,
* and EVENT_WRITE is a writeable file descriptor.
* EVENT_ERROR can always occur, and indicates
* a write error or read error on the socket,
* e.g. EOF condition or broken pipe.
*/
enum EventType
{
/** Read event */
EVENT_READ = 0,
/** Write event */
EVENT_WRITE = 1,
/** Error event */
EVENT_ERROR = 2
};
class InspIRCd;
/** This class is a basic I/O handler class.
* Any object which wishes to receive basic I/O events
* from the socketengine must derive from this class and
* implement the HandleEvent() method. The derived class
* must then be added to SocketEngine using the method
* SocketEngine::AddFd(), after which point the derived
* class will receive events to its HandleEvent() method.
* The derived class should also implement one of Readable()
* and Writeable(). In the current implementation, only
* Readable() is used. If this returns true, the socketengine
* inserts a readable socket. If it is false, the socketengine
* inserts a writeable socket. The derived class should never
* change the value this function returns without first
* deleting the socket from the socket engine. The only
* requirement beyond this for an event handler is that it
* must have a file descriptor. What this file descriptor
* is actually attached to is completely up to you.
*/
class CoreExport EventHandler : public Extensible
{
protected:
/** File descriptor.
* All events which can be handled
* must have a file descriptor.
* This allows you to add events for
* sockets, fifo's, pipes, and various
* other forms of IPC.
*/
int fd;
public:
/** Get the current file descriptor
* @return The file descriptor of this handler
*/
int GetFd();
/** Set a new file desciptor
* @param FD The new file descriptor. Do not
* call this method without first deleting the
* object from the SocketEngine if you have
* added it to a SocketEngine instance.
*/
void SetFd(int FD);
/** Constructor
*/
EventHandler() {}
/** Destructor
*/
virtual ~EventHandler() {}
/** Override this function to indicate readability.
* @return This should return true if the function
* wishes to receive EVENT_READ events. Do not change
* what this function returns while the event handler
* is still added to a SocketEngine instance!
* If this function is unimplemented, the base class
* will return true.
*
* NOTE: You cannot set both Readable() and
* Writeable() to true. If you wish to receive
* a write event for your object, you must call
* SocketEngine::WantWrite() instead. This will
* trigger your objects next EVENT_WRITE type event.
*/
virtual bool Readable();
/** Override this function to indicate writeability.
* @return This should return true if the function
* wishes to receive EVENT_WRITE events. Do not change
* what this function returns while the event handler
* is still added to a SocketEngine instance!
* If this function is unimplemented, the base class
* will return false.
*
* NOTE: You cannot set both Readable() and
* Writeable() to true. If you wish to receive
* a write event for your object, you must call
* SocketEngine::WantWrite() instead. This will
* trigger your objects next EVENT_WRITE type event.
*/
virtual bool Writeable();
/** Process an I/O event.
* You MUST implement this function in your derived
* class, and it will be called whenever read or write
* events are received, depending on what your functions
* Readable() and Writeable() returns and wether you
* previously made a call to SocketEngine::WantWrite().
* @param et either one of EVENT_READ for read events,
* and EVENT_WRITE for write events.
*/
virtual void HandleEvent(EventType et, int errornum = 0) = 0;
#ifdef WINDOWS
/** "Fake" file descriptor. This is windows-specific.
*/
int m_internalFd;
/** Pointer to read event. We delete this so the buffer can't be used
* after the socket is deleted, and so it doesn't leak memory
*/
void* m_readEvent;
/** Pointer to a write event.
*/
void* m_writeEvent;
/** Pointer to an accept event.
*/
void* m_acceptEvent;
#endif
};
/** Provides basic file-descriptor-based I/O support.
* The actual socketengine class presents the
* same interface on all operating systems, but
* its private members and internal behaviour
* should be treated as blackboxed, and vary
* from system to system and upon the config
* settings chosen by the server admin. The current
* version supports select, epoll and kqueue.
* The configure script will enable a socket engine
* based upon what OS is detected, and will derive
* a class from SocketEngine based upon what it finds.
* The derived classes file will also implement a
* classfactory, SocketEngineFactory, which will
* create a derived instance of SocketEngine using
* polymorphism so that the core and modules do not
* have to be aware of which SocketEngine derived
* class they are using.
*/
class CoreExport SocketEngine : public Extensible
{
protected:
/** Owner/Creator
*/
InspIRCd* ServerInstance;
/** Handle to socket engine, where needed.
*/
int EngineHandle;
/** Current number of descriptors in the engine
*/
int CurrentSetSize;
/** Reference table, contains all current handlers
*/
EventHandler* ref[MAX_DESCRIPTORS];
public:
/** Constructor.
* The constructor transparently initializes
* the socket engine which the ircd is using.
* Please note that if there is a catastrophic
* failure (for example, you try and enable
* epoll on a 2.4 linux kernel) then this
* function may bail back to the shell.
* @param Instance The creator/owner of this object
*/
SocketEngine(InspIRCd* Instance);
/** Destructor.
* The destructor transparently tidies up
* any resources used by the socket engine.
*/
virtual ~SocketEngine();
/** Add an EventHandler object to the engine.
* Use AddFd to add a file descriptor to the
* engine and have the socket engine monitor
* it. You must provide an object derived from
* EventHandler which implements HandleEvent()
* and optionally Readable() and Writeable().
* @param eh An event handling object to add
*/
virtual bool AddFd(EventHandler* eh);
/** If you call this function and pass it an
* event handler, that event handler will
* receive the next available write event,
* even if the socket is a readable socket only.
* Developers should avoid constantly keeping
* an eventhandler in the writeable state,
* as this will consume large amounts of
* CPU time.
* @param eh An event handler which wants to
* receive the next writeability event.
*/
virtual void WantWrite(EventHandler* eh);
/** Returns the maximum number of file descriptors
* you may store in the socket engine at any one time.
* @return The maximum fd value
*/
virtual int GetMaxFds();
/** Returns the number of file descriptor slots
* which are available for storing fds.
* @return The number of remaining fd's
*/
virtual int GetRemainingFds();
/** Delete an event handler from the engine.
* This function call deletes an EventHandler
* from the engine, returning true if it succeeded
* and false if it failed. This does not free the
* EventHandler pointer using delete, if this is
* required you must do this yourself.
* Note on forcing deletes. DO NOT DO THIS! This is
* extremely dangerous and will most likely render the
* socketengine dead. This was added only for handling
* very rare cases where broken 3rd party libs destroys
* the OS socket beyond our control. If you can't explain
* in minute details why forcing is absolutely necessary
* then you don't need it. That was a NO!
* @param eh The event handler object to remove
* @param force *DANGEROUS* See method description!
* @return True if the event handler was removed
*/
virtual bool DelFd(EventHandler* eh, bool force = false);
/** Returns true if a file descriptor exists in
* the socket engine's list.
* @param fd The event handler to look for
* @return True if this fd has an event handler
*/
virtual bool HasFd(int fd);
/** Returns the EventHandler attached to a specific fd.
* If the fd isnt in the socketengine, returns NULL.
* @param fd The event handler to look for
* @return A pointer to the event handler, or NULL
*/
virtual EventHandler* GetRef(int fd);
/** Waits for events and dispatches them to handlers.
* Please note that this doesnt wait long, only
* a couple of milliseconds. It returns the number of
* events which occured during this call.
* This method will dispatch events to their handlers
* by calling their EventHandler::HandleEvent()
* methods with the neccessary EventType value.
* @return The number of events which have occured.
*/
virtual int DispatchEvents();
/** Returns the socket engines name.
* This returns the name of the engine for use
* in /VERSION responses.
* @return The socket engine name
*/
virtual std::string GetName();
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __SOCKETENGINE__ +#define __SOCKETENGINE__ + +#include <vector> +#include <string> +#include <map> +#include "inspircd_config.h" +#include "base.h" + +/** Types of event an EventHandler may receive. + * EVENT_READ is a readable file descriptor, + * and EVENT_WRITE is a writeable file descriptor. + * EVENT_ERROR can always occur, and indicates + * a write error or read error on the socket, + * e.g. EOF condition or broken pipe. + */ +enum EventType +{ + /** Read event */ + EVENT_READ = 0, + /** Write event */ + EVENT_WRITE = 1, + /** Error event */ + EVENT_ERROR = 2 +}; + +class InspIRCd; + +/** This class is a basic I/O handler class. + * Any object which wishes to receive basic I/O events + * from the socketengine must derive from this class and + * implement the HandleEvent() method. The derived class + * must then be added to SocketEngine using the method + * SocketEngine::AddFd(), after which point the derived + * class will receive events to its HandleEvent() method. + * The derived class should also implement one of Readable() + * and Writeable(). In the current implementation, only + * Readable() is used. If this returns true, the socketengine + * inserts a readable socket. If it is false, the socketengine + * inserts a writeable socket. The derived class should never + * change the value this function returns without first + * deleting the socket from the socket engine. The only + * requirement beyond this for an event handler is that it + * must have a file descriptor. What this file descriptor + * is actually attached to is completely up to you. + */ +class CoreExport EventHandler : public Extensible +{ + protected: + /** File descriptor. + * All events which can be handled + * must have a file descriptor. + * This allows you to add events for + * sockets, fifo's, pipes, and various + * other forms of IPC. + */ + int fd; + public: + /** Get the current file descriptor + * @return The file descriptor of this handler + */ + int GetFd(); + + /** Set a new file desciptor + * @param FD The new file descriptor. Do not + * call this method without first deleting the + * object from the SocketEngine if you have + * added it to a SocketEngine instance. + */ + void SetFd(int FD); + + /** Constructor + */ + EventHandler() {} + + /** Destructor + */ + virtual ~EventHandler() {} + + /** Override this function to indicate readability. + * @return This should return true if the function + * wishes to receive EVENT_READ events. Do not change + * what this function returns while the event handler + * is still added to a SocketEngine instance! + * If this function is unimplemented, the base class + * will return true. + * + * NOTE: You cannot set both Readable() and + * Writeable() to true. If you wish to receive + * a write event for your object, you must call + * SocketEngine::WantWrite() instead. This will + * trigger your objects next EVENT_WRITE type event. + */ + virtual bool Readable(); + + /** Override this function to indicate writeability. + * @return This should return true if the function + * wishes to receive EVENT_WRITE events. Do not change + * what this function returns while the event handler + * is still added to a SocketEngine instance! + * If this function is unimplemented, the base class + * will return false. + * + * NOTE: You cannot set both Readable() and + * Writeable() to true. If you wish to receive + * a write event for your object, you must call + * SocketEngine::WantWrite() instead. This will + * trigger your objects next EVENT_WRITE type event. + */ + virtual bool Writeable(); + + /** Process an I/O event. + * You MUST implement this function in your derived + * class, and it will be called whenever read or write + * events are received, depending on what your functions + * Readable() and Writeable() returns and wether you + * previously made a call to SocketEngine::WantWrite(). + * @param et either one of EVENT_READ for read events, + * and EVENT_WRITE for write events. + */ + virtual void HandleEvent(EventType et, int errornum = 0) = 0; + +#ifdef WINDOWS + + /** "Fake" file descriptor. This is windows-specific. + */ + int m_internalFd; + + /** Pointer to read event. We delete this so the buffer can't be used + * after the socket is deleted, and so it doesn't leak memory + */ + void* m_readEvent; + /** Pointer to a write event. + */ + void* m_writeEvent; + /** Pointer to an accept event. + */ + void* m_acceptEvent; + +#endif +}; + +/** Provides basic file-descriptor-based I/O support. + * The actual socketengine class presents the + * same interface on all operating systems, but + * its private members and internal behaviour + * should be treated as blackboxed, and vary + * from system to system and upon the config + * settings chosen by the server admin. The current + * version supports select, epoll and kqueue. + * The configure script will enable a socket engine + * based upon what OS is detected, and will derive + * a class from SocketEngine based upon what it finds. + * The derived classes file will also implement a + * classfactory, SocketEngineFactory, which will + * create a derived instance of SocketEngine using + * polymorphism so that the core and modules do not + * have to be aware of which SocketEngine derived + * class they are using. + */ +class CoreExport SocketEngine : public Extensible +{ +protected: + /** Owner/Creator + */ + InspIRCd* ServerInstance; + /** Handle to socket engine, where needed. + */ + int EngineHandle; + /** Current number of descriptors in the engine + */ + int CurrentSetSize; + /** Reference table, contains all current handlers + */ + EventHandler* ref[MAX_DESCRIPTORS]; +public: + + /** Constructor. + * The constructor transparently initializes + * the socket engine which the ircd is using. + * Please note that if there is a catastrophic + * failure (for example, you try and enable + * epoll on a 2.4 linux kernel) then this + * function may bail back to the shell. + * @param Instance The creator/owner of this object + */ + SocketEngine(InspIRCd* Instance); + + /** Destructor. + * The destructor transparently tidies up + * any resources used by the socket engine. + */ + virtual ~SocketEngine(); + + /** Add an EventHandler object to the engine. + * Use AddFd to add a file descriptor to the + * engine and have the socket engine monitor + * it. You must provide an object derived from + * EventHandler which implements HandleEvent() + * and optionally Readable() and Writeable(). + * @param eh An event handling object to add + */ + virtual bool AddFd(EventHandler* eh); + + /** If you call this function and pass it an + * event handler, that event handler will + * receive the next available write event, + * even if the socket is a readable socket only. + * Developers should avoid constantly keeping + * an eventhandler in the writeable state, + * as this will consume large amounts of + * CPU time. + * @param eh An event handler which wants to + * receive the next writeability event. + */ + virtual void WantWrite(EventHandler* eh); + + /** Returns the maximum number of file descriptors + * you may store in the socket engine at any one time. + * @return The maximum fd value + */ + virtual int GetMaxFds(); + + /** Returns the number of file descriptor slots + * which are available for storing fds. + * @return The number of remaining fd's + */ + virtual int GetRemainingFds(); + + /** Delete an event handler from the engine. + * This function call deletes an EventHandler + * from the engine, returning true if it succeeded + * and false if it failed. This does not free the + * EventHandler pointer using delete, if this is + * required you must do this yourself. + * Note on forcing deletes. DO NOT DO THIS! This is + * extremely dangerous and will most likely render the + * socketengine dead. This was added only for handling + * very rare cases where broken 3rd party libs destroys + * the OS socket beyond our control. If you can't explain + * in minute details why forcing is absolutely necessary + * then you don't need it. That was a NO! + * @param eh The event handler object to remove + * @param force *DANGEROUS* See method description! + * @return True if the event handler was removed + */ + virtual bool DelFd(EventHandler* eh, bool force = false); + + /** Returns true if a file descriptor exists in + * the socket engine's list. + * @param fd The event handler to look for + * @return True if this fd has an event handler + */ + virtual bool HasFd(int fd); + + /** Returns the EventHandler attached to a specific fd. + * If the fd isnt in the socketengine, returns NULL. + * @param fd The event handler to look for + * @return A pointer to the event handler, or NULL + */ + virtual EventHandler* GetRef(int fd); + + /** Waits for events and dispatches them to handlers. + * Please note that this doesnt wait long, only + * a couple of milliseconds. It returns the number of + * events which occured during this call. + * This method will dispatch events to their handlers + * by calling their EventHandler::HandleEvent() + * methods with the neccessary EventType value. + * @return The number of events which have occured. + */ + virtual int DispatchEvents(); + + /** Returns the socket engines name. + * This returns the name of the engine for use + * in /VERSION responses. + * @return The socket engine name + */ + virtual std::string GetName(); +}; + +#endif + diff --git a/include/socketengine_epoll.h b/include/socketengine_epoll.h index ddb738fb9..736a109eb 100644 --- a/include/socketengine_epoll.h +++ b/include/socketengine_epoll.h @@ -1 +1,64 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __SOCKETENGINE_EPOLL__
#define __SOCKETENGINE_EPOLL__
#include <vector>
#include <string>
#include <map>
#include "inspircd_config.h"
#include "globals.h"
#include "inspircd.h"
#include "socketengine.h"
#include <sys/epoll.h>
#define EP_DELAY 5
class InspIRCd;
/** A specialisation of the SocketEngine class, designed to use linux 2.6 epoll().
*/
class EPollEngine : public SocketEngine
{
private:
/** These are used by epoll() to hold socket events
*/
struct epoll_event events[MAX_DESCRIPTORS];
public:
/** Create a new EPollEngine
* @param Instance The creator of this object
*/
EPollEngine(InspIRCd* Instance);
/** Delete an EPollEngine
*/
virtual ~EPollEngine();
virtual bool AddFd(EventHandler* eh);
virtual int GetMaxFds();
virtual int GetRemainingFds();
virtual bool DelFd(EventHandler* eh, bool force = false);
virtual int DispatchEvents();
virtual std::string GetName();
virtual void WantWrite(EventHandler* eh);
};
/** Creates a SocketEngine
*/
class SocketEngineFactory
{
public:
/** Create a new instance of SocketEngine based on EpollEngine
*/
SocketEngine* Create(InspIRCd* Instance) { return new EPollEngine(Instance); }
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __SOCKETENGINE_EPOLL__ +#define __SOCKETENGINE_EPOLL__ + +#include <vector> +#include <string> +#include <map> +#include "inspircd_config.h" +#include "globals.h" +#include "inspircd.h" +#include "socketengine.h" +#include <sys/epoll.h> +#define EP_DELAY 5 + +class InspIRCd; + +/** A specialisation of the SocketEngine class, designed to use linux 2.6 epoll(). + */ +class EPollEngine : public SocketEngine +{ +private: + /** These are used by epoll() to hold socket events + */ + struct epoll_event events[MAX_DESCRIPTORS]; +public: + /** Create a new EPollEngine + * @param Instance The creator of this object + */ + EPollEngine(InspIRCd* Instance); + /** Delete an EPollEngine + */ + virtual ~EPollEngine(); + virtual bool AddFd(EventHandler* eh); + virtual int GetMaxFds(); + virtual int GetRemainingFds(); + virtual bool DelFd(EventHandler* eh, bool force = false); + virtual int DispatchEvents(); + virtual std::string GetName(); + virtual void WantWrite(EventHandler* eh); +}; + +/** Creates a SocketEngine + */ +class SocketEngineFactory +{ +public: + /** Create a new instance of SocketEngine based on EpollEngine + */ + SocketEngine* Create(InspIRCd* Instance) { return new EPollEngine(Instance); } +}; + +#endif diff --git a/include/socketengine_iocp.h b/include/socketengine_iocp.h index ac27c86e3..f4825c6b4 100644 --- a/include/socketengine_iocp.h +++ b/include/socketengine_iocp.h @@ -1 +1,226 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __SOCKETENGINE_IOCP__
#define __SOCKETENGINE_IOCP__
#define READ_BUFFER_SIZE 600
#define USING_IOCP 1
#include "inspircd_config.h"
#include "inspircd_win32wrapper.h"
#include "globals.h"
#include "inspircd.h"
#include "socketengine.h"
/** Socket overlapped event types
*/
enum SocketIOEvent
{
/** Read ready */
SOCKET_IO_EVENT_READ_READY = 0,
/** Write ready */
SOCKET_IO_EVENT_WRITE_READY = 1,
/** Accept ready */
SOCKET_IO_EVENT_ACCEPT = 2,
/** Error occured */
SOCKET_IO_EVENT_ERROR = 3,
/** Number of events */
NUM_SOCKET_IO_EVENTS = 4,
};
/** Represents a windows overlapped IO event
*/
class Overlapped
{
public:
/** Overlap event */
OVERLAPPED m_overlap;
/** Type of event */
SocketIOEvent m_event;
#ifdef WIN64
/** Parameters */
unsigned __int64 m_params;
#else
/** Parameters */
unsigned long m_params;
#endif
/** Create an overlapped event
*/
Overlapped(SocketIOEvent ev, int params) : m_event(ev), m_params(params)
{
memset(&m_overlap, 0, sizeof(OVERLAPPED));
}
};
/** Specific to UDP sockets with overlapped IO
*/
struct udp_overlap
{
unsigned char udp_buffer[600];
unsigned long udp_len;
sockaddr udp_sockaddr[2];
unsigned long udp_sockaddr_len;
};
/** Specific to accepting sockets with overlapped IO
*/
struct accept_overlap
{
int socket;
char buf[1024];
};
/** Implementation of SocketEngine that implements windows IO Completion Ports
*/
class IOCPEngine : public SocketEngine
{
/** Creates a "fake" file descriptor for use with an IOCP socket.
* This is a little slow, but it isnt called too much. We'll fix it
* in a future release.
* @return -1 if there are no free slots, and an integer if it finds one.
*/
__inline int GenerateFd(int RealFd)
{
int index_hash = RealFd % MAX_DESCRIPTORS;
if(ref[index_hash] == 0)
return index_hash;
else
{
register int i = 0;
for(; i < MAX_DESCRIPTORS; ++i)
if(ref[i] == 0)
return i;
}
return -1;
}
/** Global I/O completion port that sockets attach to.
*/
HANDLE m_completionPort;
/** This is kinda shitty... :/ for getting an address from a real fd.
*/
map<int, EventHandler*> m_binding;
public:
/** Creates an IOCP Socket Engine
* @param Instance The creator of this object
*/
IOCPEngine(InspIRCd* Instance);
/** Deletes an IOCP socket engine and all the attached sockets
*/
~IOCPEngine();
/** Adds an event handler to the completion port, and sets up initial events.
* @param eh EventHandler to add
* @return True if success, false if no room
*/
bool AddFd(EventHandler* eh);
/** Gets the maximum number of file descriptors that this engine can handle.
* @return The number of file descriptors
*/
__inline int GetMaxFds() { return MAX_DESCRIPTORS; }
/** Gets the number of free/remaining file descriptors under this engine.
* @return Remaining count
*/
__inline int GetRemainingFds()
{
register int count = 0;
register int i = 0;
for(; i < MAX_DESCRIPTORS; ++i)
if(ref[i] == 0)
++count;
return count;
}
/** Removes a file descriptor from the set, preventing it from receiving any more events
* @return True if remove was successful, false otherwise
*/
bool DelFd(EventHandler* eh, bool force = false);
/** Called every loop to handle input/output events for all sockets under this engine
* @return The number of "changed" sockets.
*/
int DispatchEvents();
/** Gets the name of this socket engine as a string.
* @return string of socket engine name
*/
std::string GetName();
/** Queues a Write event on the specified event handler.
* @param eh EventHandler that needs data sent on
*/
void WantWrite(EventHandler* eh);
/** Posts a completion event on the specified socket.
* @param eh EventHandler for message
* @param type Event Type
* @param param Event Parameter
* @return True if added, false if not
*/
bool PostCompletionEvent(EventHandler* eh, SocketIOEvent type, int param);
/** Posts a read event on the specified socket
* @param eh EventHandler (socket)
*/
void PostReadEvent(EventHandler* eh);
/** Posts an accept event on the specified socket
* @param eh EventHandler (socket)
*/
void PostAcceptEvent(EventHandler* eh);
/** Returns the EventHandler attached to a specific fd.
* If the fd isnt in the socketengine, returns NULL.
* @param fd The event handler to look for
* @return A pointer to the event handler, or NULL
*/
EventHandler* GetRef(int fd);
/** Returns true if a file descriptor exists in
* the socket engine's list.
* @param fd The event handler to look for
* @return True if this fd has an event handler
*/
bool HasFd(int fd);
/** Returns the EventHandler attached to a specific fd.
* If the fd isnt in the socketengine, returns NULL.
* @param fd The event handler to look for
* @return A pointer to the event handler, or NULL
*/
EventHandler* GetIntRef(int fd);
/** Holds the preallocated buffer passed to WSARecvFrom
* function. Yes, I know, it's a dirty hack.
*/
udp_overlap * udp_ov;
};
/** Creates a SocketEngine
*/
class SocketEngineFactory
{
public:
/** Create a new instance of SocketEngine based on IOCPEngine
*/
SocketEngine* Create(InspIRCd* Instance) { return new IOCPEngine(Instance); }
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __SOCKETENGINE_IOCP__ +#define __SOCKETENGINE_IOCP__ + +#define READ_BUFFER_SIZE 600 +#define USING_IOCP 1 + +#include "inspircd_config.h" +#include "inspircd_win32wrapper.h" +#include "globals.h" +#include "inspircd.h" +#include "socketengine.h" + +/** Socket overlapped event types + */ +enum SocketIOEvent +{ + /** Read ready */ + SOCKET_IO_EVENT_READ_READY = 0, + /** Write ready */ + SOCKET_IO_EVENT_WRITE_READY = 1, + /** Accept ready */ + SOCKET_IO_EVENT_ACCEPT = 2, + /** Error occured */ + SOCKET_IO_EVENT_ERROR = 3, + /** Number of events */ + NUM_SOCKET_IO_EVENTS = 4, +}; + +/** Represents a windows overlapped IO event + */ +class Overlapped +{ + public: + /** Overlap event */ + OVERLAPPED m_overlap; + /** Type of event */ + SocketIOEvent m_event; +#ifdef WIN64 + /** Parameters */ + unsigned __int64 m_params; +#else + /** Parameters */ + unsigned long m_params; +#endif + /** Create an overlapped event + */ + Overlapped(SocketIOEvent ev, int params) : m_event(ev), m_params(params) + { + memset(&m_overlap, 0, sizeof(OVERLAPPED)); + } +}; + +/** Specific to UDP sockets with overlapped IO + */ +struct udp_overlap +{ + unsigned char udp_buffer[600]; + unsigned long udp_len; + sockaddr udp_sockaddr[2]; + unsigned long udp_sockaddr_len; +}; + +/** Specific to accepting sockets with overlapped IO + */ +struct accept_overlap +{ + int socket; + char buf[1024]; +}; + +/** Implementation of SocketEngine that implements windows IO Completion Ports + */ +class IOCPEngine : public SocketEngine +{ + /** Creates a "fake" file descriptor for use with an IOCP socket. + * This is a little slow, but it isnt called too much. We'll fix it + * in a future release. + * @return -1 if there are no free slots, and an integer if it finds one. + */ + __inline int GenerateFd(int RealFd) + { + int index_hash = RealFd % MAX_DESCRIPTORS; + if(ref[index_hash] == 0) + return index_hash; + else + { + register int i = 0; + for(; i < MAX_DESCRIPTORS; ++i) + if(ref[i] == 0) + return i; + } + return -1; + } + + /** Global I/O completion port that sockets attach to. + */ + HANDLE m_completionPort; + + /** This is kinda shitty... :/ for getting an address from a real fd. + */ + map<int, EventHandler*> m_binding; + +public: + /** Creates an IOCP Socket Engine + * @param Instance The creator of this object + */ + IOCPEngine(InspIRCd* Instance); + + /** Deletes an IOCP socket engine and all the attached sockets + */ + ~IOCPEngine(); + + /** Adds an event handler to the completion port, and sets up initial events. + * @param eh EventHandler to add + * @return True if success, false if no room + */ + bool AddFd(EventHandler* eh); + + /** Gets the maximum number of file descriptors that this engine can handle. + * @return The number of file descriptors + */ + __inline int GetMaxFds() { return MAX_DESCRIPTORS; } + + /** Gets the number of free/remaining file descriptors under this engine. + * @return Remaining count + */ + __inline int GetRemainingFds() + { + register int count = 0; + register int i = 0; + for(; i < MAX_DESCRIPTORS; ++i) + if(ref[i] == 0) + ++count; + return count; + } + + /** Removes a file descriptor from the set, preventing it from receiving any more events + * @return True if remove was successful, false otherwise + */ + bool DelFd(EventHandler* eh, bool force = false); + + /** Called every loop to handle input/output events for all sockets under this engine + * @return The number of "changed" sockets. + */ + int DispatchEvents(); + + /** Gets the name of this socket engine as a string. + * @return string of socket engine name + */ + std::string GetName(); + + /** Queues a Write event on the specified event handler. + * @param eh EventHandler that needs data sent on + */ + void WantWrite(EventHandler* eh); + + /** Posts a completion event on the specified socket. + * @param eh EventHandler for message + * @param type Event Type + * @param param Event Parameter + * @return True if added, false if not + */ + bool PostCompletionEvent(EventHandler* eh, SocketIOEvent type, int param); + + /** Posts a read event on the specified socket + * @param eh EventHandler (socket) + */ + void PostReadEvent(EventHandler* eh); + + /** Posts an accept event on the specified socket + * @param eh EventHandler (socket) + */ + void PostAcceptEvent(EventHandler* eh); + + /** Returns the EventHandler attached to a specific fd. + * If the fd isnt in the socketengine, returns NULL. + * @param fd The event handler to look for + * @return A pointer to the event handler, or NULL + */ + EventHandler* GetRef(int fd); + + /** Returns true if a file descriptor exists in + * the socket engine's list. + * @param fd The event handler to look for + * @return True if this fd has an event handler + */ + bool HasFd(int fd); + + /** Returns the EventHandler attached to a specific fd. + * If the fd isnt in the socketengine, returns NULL. + * @param fd The event handler to look for + * @return A pointer to the event handler, or NULL + */ + EventHandler* GetIntRef(int fd); + + /** Holds the preallocated buffer passed to WSARecvFrom + * function. Yes, I know, it's a dirty hack. + */ + udp_overlap * udp_ov; +}; + +/** Creates a SocketEngine + */ +class SocketEngineFactory +{ +public: + /** Create a new instance of SocketEngine based on IOCPEngine + */ + SocketEngine* Create(InspIRCd* Instance) { return new IOCPEngine(Instance); } +}; + +#endif + diff --git a/include/socketengine_kqueue.h b/include/socketengine_kqueue.h index b05d40520..e7413d4bb 100644 --- a/include/socketengine_kqueue.h +++ b/include/socketengine_kqueue.h @@ -1 +1,68 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __SOCKETENGINE_KQUEUE__
#define __SOCKETENGINE_KQUEUE__
#include <vector>
#include <string>
#include <map>
#include "inspircd_config.h"
#include "globals.h"
#include "inspircd.h"
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include "socketengine.h"
class InspIRCd;
/** A specialisation of the SocketEngine class, designed to use FreeBSD kqueue().
*/
class KQueueEngine : public SocketEngine
{
private:
/** These are used by kqueue() to hold socket events
*/
struct kevent ke_list[MAX_DESCRIPTORS];
/** This is a specialised time value used by kqueue()
*/
struct timespec ts;
public:
/** Create a new KQueueEngine
* @param Instance The creator of this object
*/
KQueueEngine(InspIRCd* Instance);
/** Delete a KQueueEngine
*/
virtual ~KQueueEngine();
virtual bool AddFd(EventHandler* eh);
virtual int GetMaxFds();
virtual int GetRemainingFds();
virtual bool DelFd(EventHandler* eh, bool force = false);
virtual int DispatchEvents();
virtual std::string GetName();
virtual void WantWrite(EventHandler* eh);
};
/** Creates a SocketEngine
*/
class SocketEngineFactory
{
public:
/** Create a new instance of SocketEngine based on KQueueEngine
*/
SocketEngine* Create(InspIRCd* Instance) { return new KQueueEngine(Instance); }
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __SOCKETENGINE_KQUEUE__ +#define __SOCKETENGINE_KQUEUE__ + +#include <vector> +#include <string> +#include <map> +#include "inspircd_config.h" +#include "globals.h" +#include "inspircd.h" +#include <sys/types.h> +#include <sys/event.h> +#include <sys/time.h> +#include "socketengine.h" + +class InspIRCd; + +/** A specialisation of the SocketEngine class, designed to use FreeBSD kqueue(). + */ +class KQueueEngine : public SocketEngine +{ +private: + /** These are used by kqueue() to hold socket events + */ + struct kevent ke_list[MAX_DESCRIPTORS]; + /** This is a specialised time value used by kqueue() + */ + struct timespec ts; +public: + /** Create a new KQueueEngine + * @param Instance The creator of this object + */ + KQueueEngine(InspIRCd* Instance); + /** Delete a KQueueEngine + */ + virtual ~KQueueEngine(); + virtual bool AddFd(EventHandler* eh); + virtual int GetMaxFds(); + virtual int GetRemainingFds(); + virtual bool DelFd(EventHandler* eh, bool force = false); + virtual int DispatchEvents(); + virtual std::string GetName(); + virtual void WantWrite(EventHandler* eh); +}; + +/** Creates a SocketEngine + */ +class SocketEngineFactory +{ + public: + /** Create a new instance of SocketEngine based on KQueueEngine + */ + SocketEngine* Create(InspIRCd* Instance) { return new KQueueEngine(Instance); } +}; + +#endif diff --git a/include/socketengine_ports.h b/include/socketengine_ports.h index 72b5da671..a5951a138 100644 --- a/include/socketengine_ports.h +++ b/include/socketengine_ports.h @@ -1 +1,68 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __SOCKETENGINE_PORTS__
#define __SOCKETENGINE_PORTS__
#ifndef __sun
# error You need Solaris 10 or later to make use of this code.
#endif
#include <vector>
#include <string>
#include <map>
#include "inspircd_config.h"
#include "globals.h"
#include "inspircd.h"
#include "socketengine.h"
#include <port.h>
class InspIRCd;
/** A specialisation of the SocketEngine class, designed to use solaris 10 I/O completion ports
*/
class PortsEngine : public SocketEngine
{
private:
/** These are used by epoll() to hold socket events
*/
port_event_t events[MAX_DESCRIPTORS];
public:
/** Create a new PortsEngine
* @param Instance The creator of this object
*/
PortsEngine(InspIRCd* Instance);
/** Delete a PortsEngine
*/
virtual ~PortsEngine();
virtual bool AddFd(EventHandler* eh);
virtual int GetMaxFds();
virtual int GetRemainingFds();
virtual bool DelFd(EventHandler* eh, bool force = false);
virtual int DispatchEvents();
virtual std::string GetName();
virtual void WantWrite(EventHandler* eh);
};
/** Creates a SocketEngine
*/
class SocketEngineFactory
{
public:
/** Create a new instance of SocketEngine based on PortsEngine
*/
SocketEngine* Create(InspIRCd* Instance) { return new PortsEngine(Instance); }
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __SOCKETENGINE_PORTS__ +#define __SOCKETENGINE_PORTS__ + +#ifndef __sun +# error You need Solaris 10 or later to make use of this code. +#endif + +#include <vector> +#include <string> +#include <map> +#include "inspircd_config.h" +#include "globals.h" +#include "inspircd.h" +#include "socketengine.h" +#include <port.h> + +class InspIRCd; + +/** A specialisation of the SocketEngine class, designed to use solaris 10 I/O completion ports + */ +class PortsEngine : public SocketEngine +{ +private: + /** These are used by epoll() to hold socket events + */ + port_event_t events[MAX_DESCRIPTORS]; +public: + /** Create a new PortsEngine + * @param Instance The creator of this object + */ + PortsEngine(InspIRCd* Instance); + /** Delete a PortsEngine + */ + virtual ~PortsEngine(); + virtual bool AddFd(EventHandler* eh); + virtual int GetMaxFds(); + virtual int GetRemainingFds(); + virtual bool DelFd(EventHandler* eh, bool force = false); + virtual int DispatchEvents(); + virtual std::string GetName(); + virtual void WantWrite(EventHandler* eh); +}; + +/** Creates a SocketEngine + */ +class SocketEngineFactory +{ +public: + /** Create a new instance of SocketEngine based on PortsEngine + */ + SocketEngine* Create(InspIRCd* Instance) { return new PortsEngine(Instance); } +}; + +#endif + diff --git a/include/socketengine_select.h b/include/socketengine_select.h index 553acdea2..2126e8ec5 100644 --- a/include/socketengine_select.h +++ b/include/socketengine_select.h @@ -1 +1,69 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __SOCKETENGINE_SELECT__
#define __SOCKETENGINE_SELECT__
#include <vector>
#include <string>
#include <map>
#include <sys/select.h>
#include "inspircd_config.h"
#include "globals.h"
#include "inspircd.h"
#include "socketengine.h"
class InspIRCd;
/** A specialisation of the SocketEngine class, designed to use traditional select().
*/
class SelectEngine : public SocketEngine
{
private:
/** Because select() does not track an fd list for us between calls, we have one of our own
*/
std::map<int,int> fds;
/** List of writeable ones (WantWrite())
*/
bool writeable[MAX_DESCRIPTORS];
/** The read set and write set, populated before each call to select().
*/
fd_set wfdset, rfdset, errfdset;
public:
/** Create a new SelectEngine
* @param Instance The creator of this object
*/
SelectEngine(InspIRCd* Instance);
/** Delete a SelectEngine
*/
virtual ~SelectEngine();
virtual bool AddFd(EventHandler* eh);
virtual int GetMaxFds();
virtual int GetRemainingFds();
virtual bool DelFd(EventHandler* eh, bool force = false);
virtual int DispatchEvents();
virtual std::string GetName();
virtual void WantWrite(EventHandler* eh);
};
/** Creates a SocketEngine
*/
class SocketEngineFactory
{
public:
/** Create a new instance of SocketEngine based on SelectEngine
*/
SocketEngine* Create(InspIRCd* Instance) { return new SelectEngine(Instance); }
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __SOCKETENGINE_SELECT__ +#define __SOCKETENGINE_SELECT__ + +#include <vector> +#include <string> +#include <map> +#include <sys/select.h> +#include "inspircd_config.h" +#include "globals.h" +#include "inspircd.h" +#include "socketengine.h" + +class InspIRCd; + +/** A specialisation of the SocketEngine class, designed to use traditional select(). + */ +class SelectEngine : public SocketEngine +{ +private: + /** Because select() does not track an fd list for us between calls, we have one of our own + */ + std::map<int,int> fds; + /** List of writeable ones (WantWrite()) + */ + bool writeable[MAX_DESCRIPTORS]; + /** The read set and write set, populated before each call to select(). + */ + fd_set wfdset, rfdset, errfdset; +public: + /** Create a new SelectEngine + * @param Instance The creator of this object + */ + SelectEngine(InspIRCd* Instance); + /** Delete a SelectEngine + */ + virtual ~SelectEngine(); + virtual bool AddFd(EventHandler* eh); + virtual int GetMaxFds(); + virtual int GetRemainingFds(); + virtual bool DelFd(EventHandler* eh, bool force = false); + virtual int DispatchEvents(); + virtual std::string GetName(); + virtual void WantWrite(EventHandler* eh); +}; + +/** Creates a SocketEngine + */ +class SocketEngineFactory +{ +public: + /** Create a new instance of SocketEngine based on SelectEngine + */ + SocketEngine* Create(InspIRCd* Instance) { return new SelectEngine(Instance); } +}; + +#endif diff --git a/include/timer.h b/include/timer.h index ad4f5ef87..ef8b82e31 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1 +1,156 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef INSPIRCD_TIMER_H
#define INSPIRCD_TIMER_H
class InspIRCd;
/** Timer class for one-second resolution timers
* InspTimer provides a facility which allows module
* developers to create one-shot timers. The timer
* can be made to trigger at any time up to a one-second
* resolution. To use InspTimer, inherit a class from
* InspTimer, then insert your inherited class into the
* queue using Server::AddTimer(). The Tick() method of
* your object (which you should override) will be called
* at the given time.
*/
class CoreExport InspTimer : public Extensible
{
private:
/** The triggering time
*/
time_t trigger;
/** Number of seconds between triggers
*/
long secs;
/** True if this is a repeating timer
*/
bool repeat;
public:
/** Default constructor, initializes the triggering time
* @param secs_from_now The number of seconds from now to trigger the timer
* @param now The time now
* @param repeating Repeat this timer every secs_from_now seconds if set to true
*/
InspTimer(long secs_from_now,time_t now, bool repeating = false)
{
trigger = now + secs_from_now;
secs = secs_from_now;
repeat = repeating;
}
/** Default destructor, does nothing.
*/
virtual ~InspTimer() { }
/** Retrieve the current triggering time
*/
virtual time_t GetTimer()
{
return trigger;
}
/** Called when the timer ticks.
* You should override this method with some useful code to
* handle the tick event.
*/
virtual void Tick(time_t TIME) = 0;
/** Returns true if this timer is set to repeat
*/
bool GetRepeat()
{
return repeat;
}
/** Returns the interval (number of seconds between ticks)
* of this timer object.
*/
long GetSecs()
{
return secs;
}
/** Cancels the repeat state of a repeating timer.
* If you call this method, then the next time your
* timer ticks, it will be removed immediately after.
* You should use this method call to remove a recurring
* timer if you wish to do so within the timer's Tick
* event, as calling TimerManager::DelTimer() from within
* the InspTimer::Tick() method is dangerous and may
* cause a segmentation fault. Calling CancelRepeat()
* is safe in this case.
*/
void CancelRepeat()
{
repeat = false;
}
};
/** This class manages sets of InspTimers, and triggers them at their defined times.
* This will ensure timers are not missed, as well as removing timers that have
* expired and allowing the addition of new ones.
*/
class CoreExport TimerManager : public Extensible
{
protected:
/** A group of timers all set to trigger at the same time
*/
typedef std::vector<InspTimer*> timergroup;
/** A map of timergroups, each group has a specific trigger time
*/
typedef std::map<time_t, timergroup*> timerlist;
/** Set when ticking timers, to prevent deletion while iterating
*/
bool CantDeleteHere;
/** Creating server instance
*/
InspIRCd* ServerInstance;
private:
/** The current timer set, a map of timergroups
*/
timerlist Timers;
public:
/** Constructor
*/
TimerManager(InspIRCd* Instance);
/** Tick all pending InspTimers
* @param TIME the current system time
*/
void TickTimers(time_t TIME);
/** Add an InspTimer
* @param T an InspTimer derived class to add
* @param secs_from_now You may set this to the number of seconds
* from the current time when the timer will tick, or you may just
* leave this unset and the values set by the InspTimers constructor
* will be used. This is used internally for re-triggering repeating
* timers.
*/
void AddTimer(InspTimer* T, long secs_from_now = 0);
/** Delete an InspTimer
* @param T an InspTimer derived class to delete
*/
void DelTimer(InspTimer* T);
/** Tick any timers that have been missed due to lag
* @param TIME the current system time
*/
void TickMissedTimers(time_t TIME);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef INSPIRCD_TIMER_H +#define INSPIRCD_TIMER_H + +class InspIRCd; + +/** Timer class for one-second resolution timers + * InspTimer provides a facility which allows module + * developers to create one-shot timers. The timer + * can be made to trigger at any time up to a one-second + * resolution. To use InspTimer, inherit a class from + * InspTimer, then insert your inherited class into the + * queue using Server::AddTimer(). The Tick() method of + * your object (which you should override) will be called + * at the given time. + */ +class CoreExport InspTimer : public Extensible +{ + private: + /** The triggering time + */ + time_t trigger; + /** Number of seconds between triggers + */ + long secs; + /** True if this is a repeating timer + */ + bool repeat; + public: + /** Default constructor, initializes the triggering time + * @param secs_from_now The number of seconds from now to trigger the timer + * @param now The time now + * @param repeating Repeat this timer every secs_from_now seconds if set to true + */ + InspTimer(long secs_from_now,time_t now, bool repeating = false) + { + trigger = now + secs_from_now; + secs = secs_from_now; + repeat = repeating; + } + + /** Default destructor, does nothing. + */ + virtual ~InspTimer() { } + + /** Retrieve the current triggering time + */ + virtual time_t GetTimer() + { + return trigger; + } + + /** Called when the timer ticks. + * You should override this method with some useful code to + * handle the tick event. + */ + virtual void Tick(time_t TIME) = 0; + + /** Returns true if this timer is set to repeat + */ + bool GetRepeat() + { + return repeat; + } + + /** Returns the interval (number of seconds between ticks) + * of this timer object. + */ + long GetSecs() + { + return secs; + } + + /** Cancels the repeat state of a repeating timer. + * If you call this method, then the next time your + * timer ticks, it will be removed immediately after. + * You should use this method call to remove a recurring + * timer if you wish to do so within the timer's Tick + * event, as calling TimerManager::DelTimer() from within + * the InspTimer::Tick() method is dangerous and may + * cause a segmentation fault. Calling CancelRepeat() + * is safe in this case. + */ + void CancelRepeat() + { + repeat = false; + } +}; + + +/** This class manages sets of InspTimers, and triggers them at their defined times. + * This will ensure timers are not missed, as well as removing timers that have + * expired and allowing the addition of new ones. + */ +class CoreExport TimerManager : public Extensible +{ + protected: + /** A group of timers all set to trigger at the same time + */ + typedef std::vector<InspTimer*> timergroup; + /** A map of timergroups, each group has a specific trigger time + */ + typedef std::map<time_t, timergroup*> timerlist; + /** Set when ticking timers, to prevent deletion while iterating + */ + bool CantDeleteHere; + /** Creating server instance + */ + InspIRCd* ServerInstance; + private: + + /** The current timer set, a map of timergroups + */ + timerlist Timers; + + public: + /** Constructor + */ + TimerManager(InspIRCd* Instance); + /** Tick all pending InspTimers + * @param TIME the current system time + */ + void TickTimers(time_t TIME); + /** Add an InspTimer + * @param T an InspTimer derived class to add + * @param secs_from_now You may set this to the number of seconds + * from the current time when the timer will tick, or you may just + * leave this unset and the values set by the InspTimers constructor + * will be used. This is used internally for re-triggering repeating + * timers. + */ + void AddTimer(InspTimer* T, long secs_from_now = 0); + /** Delete an InspTimer + * @param T an InspTimer derived class to delete + */ + void DelTimer(InspTimer* T); + /** Tick any timers that have been missed due to lag + * @param TIME the current system time + */ + void TickMissedTimers(time_t TIME); +}; + +#endif + diff --git a/include/typedefs.h b/include/typedefs.h index 0c9ee3ed1..f101e1615 100644 --- a/include/typedefs.h +++ b/include/typedefs.h @@ -1 +1,53 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __TYPEDEF_H__
#define __TYPEDEF_H__
#include <string>
#include "inspircd_config.h"
#include "hash_map.h"
#include "users.h"
#include "channels.h"
#include "hashcomp.h"
#include "inspstring.h"
#include "ctables.h"
#include "modules.h"
#include "globals.h"
#ifndef WIN32
/** User hash (POSIX systems with GCC)
*/
typedef nspace::hash_map<std::string, userrec*, nspace::hash<string>, irc::StrHashComp> user_hash;
/** Channel hash (POSIX systems with GCC)
*/
typedef nspace::hash_map<std::string, chanrec*, nspace::hash<string>, irc::StrHashComp> chan_hash;
#else
/** User hash (windows systems with visual studio)
*/
typedef nspace::hash_map<std::string, userrec*, nspace::hash_compare<string, less<string> > > user_hash;
/** Channel hash (windows systems with visual studio)
*/
typedef nspace::hash_map<std::string, chanrec*, nspace::hash_compare<string, less<string> > > chan_hash;
#endif
/** Server name cache
*/
typedef std::vector<std::string*> servernamelist;
/** A cached text file stored line by line.
*/
typedef std::deque<std::string> file_cache;
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __TYPEDEF_H__ +#define __TYPEDEF_H__ + +#include <string> +#include "inspircd_config.h" +#include "hash_map.h" +#include "users.h" +#include "channels.h" +#include "hashcomp.h" +#include "inspstring.h" +#include "ctables.h" +#include "modules.h" +#include "globals.h" + +#ifndef WIN32 +/** User hash (POSIX systems with GCC) + */ +typedef nspace::hash_map<std::string, userrec*, nspace::hash<string>, irc::StrHashComp> user_hash; +/** Channel hash (POSIX systems with GCC) + */ +typedef nspace::hash_map<std::string, chanrec*, nspace::hash<string>, irc::StrHashComp> chan_hash; +#else +/** User hash (windows systems with visual studio) + */ +typedef nspace::hash_map<std::string, userrec*, nspace::hash_compare<string, less<string> > > user_hash; +/** Channel hash (windows systems with visual studio) + */ +typedef nspace::hash_map<std::string, chanrec*, nspace::hash_compare<string, less<string> > > chan_hash; +#endif + +/** Server name cache + */ +typedef std::vector<std::string*> servernamelist; + +/** A cached text file stored line by line. + */ +typedef std::deque<std::string> file_cache; + +#endif + diff --git a/include/u_listmode.h b/include/u_listmode.h index 3b2ff13d6..baf736745 100644 --- a/include/u_listmode.h +++ b/include/u_listmode.h @@ -1 +1,474 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef INSPIRCD_LISTMODE_PROVIDER
#define INSPIRCD_LISTMODE_PROVIDER
#include <stdio.h>
#include <string>
#include <sstream>
#include <vector>
#include "users.h"
#include "channels.h"
#include "modules.h"
#include "wildcard.h"
#include "inspircd.h"
/* Updated to use the <banlist> config tag if it exists
* Written by Om <omster@gmail.com>, December 2005.
* Based on code previously written by Om - April 2005
* Updated to new API July 8th 2006 by Brain
* Originally based on m_chanprotect and m_silence
*/
/** Get the time as a string
*/
inline std::string stringtime()
{
std::ostringstream TIME;
TIME << time(NULL);
return TIME.str();
}
/** An item in a listmode's list
*/
class ListItem : public classbase
{
public:
std::string nick;
irc::string mask;
std::string time;
};
/** The number of items a listmode's list may contain
*/
class ListLimit : public classbase
{
public:
std::string mask;
unsigned int limit;
};
/** Items stored in the channel's list
*/
typedef std::vector<ListItem> modelist;
/** Max items per channel by name
*/
typedef std::vector<ListLimit> limitlist;
/** A request used to check if a user is on a channel's list or not
*/
class ListModeRequest : public Request
{
public:
userrec* user;
chanrec* chan;
/** Check if a user is on a channel's list.
* The Event::Send() event returns true if the user is on the channel's list.
* @param sender Sending module
* @param target Target module
* @param u User to check against
* @param c Channel to check against
*/
ListModeRequest(Module* sender, Module* target, userrec* u, chanrec* c) : Request(sender, target, "LM_CHECKLIST"), user(u), chan(c)
{
}
/** Destructor
*/
~ListModeRequest()
{
}
};
/** The base class for list modes, should be inherited.
*/
class ListModeBase : public ModeHandler
{
protected:
/** Storage key
*/
std::string infokey;
/** Numeric to use when outputting the list
*/
std::string listnumeric;
/** Numeric to indicate end of list
*/
std::string endoflistnumeric;
/** String to send for end of list
*/
std::string endofliststring;
/** Automatically tidy up entries
*/
bool tidy;
/** Config tag to check for max items per channel
*/
std::string configtag;
/** Limits on a per-channel basis read from the tag
* specified in ListModeBase::configtag
*/
limitlist chanlimits;
public:
/** Constructor.
* @param Instance The creator of this class
* @param modechar Mode character
* @param eolstr End of list string
* @pram lnum List numeric
* @param eolnum End of list numeric
* @param autotidy Automatically tidy list entries on add
* @param ctag Configuration tag to get limits from
*/
ListModeBase(InspIRCd* Instance, char modechar, const std::string &eolstr, const std::string &lnum, const std::string &eolnum, bool autotidy, const std::string &ctag = "banlist")
: ModeHandler(Instance, modechar, 1, 1, true, MODETYPE_CHANNEL, false), listnumeric(lnum), endoflistnumeric(eolnum), endofliststring(eolstr), tidy(autotidy), configtag(ctag)
{
this->DoRehash();
infokey = "listbase_mode_" + std::string(1, mode) + "_list";
}
/** See mode.h
*/
std::pair<bool,std::string> ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter)
{
modelist* el;
channel->GetExt(infokey, el);
if (el)
{
for (modelist::iterator it = el->begin(); it != el->end(); it++)
{
if(parameter == it->mask)
{
return std::make_pair(true, parameter);
}
}
}
return std::make_pair(false, parameter);
}
/** Display the list for this mode
* @param user The user to send the list to
* @param channel The channel the user is requesting the list for
*/
virtual void DisplayList(userrec* user, chanrec* channel)
{
modelist* el;
channel->GetExt(infokey, el);
if (el)
{
for (modelist::reverse_iterator it = el->rbegin(); it != el->rend(); ++it)
{
user->WriteServ("%s %s %s %s %s %s", listnumeric.c_str(), user->nick, channel->name, it->mask.c_str(), it->nick.c_str(), it->time.c_str());
}
}
user->WriteServ("%s %s %s :%s", endoflistnumeric.c_str(), user->nick, channel->name, endofliststring.c_str());
}
/** Remove all instances of the mode from a channel.
* See mode.h
* @param channel The channel to remove all instances of the mode from
*/
virtual void RemoveMode(chanrec* channel)
{
modelist* el;
channel->GetExt(infokey, el);
if (el)
{
irc::modestacker modestack(false);
std::deque<std::string> stackresult;
const char* mode_junk[MAXMODES+2];
mode_junk[0] = channel->name;
userrec* n = new userrec(ServerInstance);
n->SetFd(FD_MAGIC_NUMBER);
for (modelist::iterator it = el->begin(); it != el->end(); it++)
{
modestack.Push(this->GetModeChar(), assign(it->mask));
}
while (modestack.GetStackedLine(stackresult))
{
for (size_t j = 0; j < stackresult.size(); j++)
{
mode_junk[j+1] = stackresult[j].c_str();
}
ServerInstance->SendMode(mode_junk, stackresult.size() + 1, n);
}
delete n;
}
}
/** See mode.h
*/
virtual void RemoveMode(userrec* user)
{
/* Listmodes dont get set on users */
}
/** Perform a rehash of this mode's configuration data
*/
virtual void DoRehash()
{
ConfigReader Conf(ServerInstance);
chanlimits.clear();
for (int i = 0; i < Conf.Enumerate(configtag); i++)
{
// For each <banlist> tag
ListLimit limit;
limit.mask = Conf.ReadValue(configtag, "chan", i);
limit.limit = Conf.ReadInteger(configtag, "limit", i, true);
if (limit.mask.size() && limit.limit > 0)
chanlimits.push_back(limit);
}
if (chanlimits.size() == 0)
{
ListLimit limit;
limit.mask = "*";
limit.limit = 64;
chanlimits.push_back(limit);
}
}
/** Populate the Implements list with the correct events for a List Mode
*/
virtual void DoImplements(char* List)
{
List[I_OnChannelDelete] = List[I_OnSyncChannel] = List[I_OnCleanup] = List[I_OnRehash] = 1;
}
/** Handle the list mode.
* See mode.h
*/
virtual ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding)
{
// Try and grab the list
modelist* el;
channel->GetExt(infokey, el);
if (adding)
{
// If there was no list
if (!el)
{
// Make one
el = new modelist;
channel->Extend(infokey, el);
}
// Clean the mask up
if (this->tidy)
ModeParser::CleanMask(parameter);
// Check if the item already exists in the list
for (modelist::iterator it = el->begin(); it != el->end(); it++)
{
if (parameter == it->mask)
{
/* Give a subclass a chance to error about this */
TellAlreadyOnList(source, channel, parameter);
// it does, deny the change
return MODEACTION_DENY;
}
}
unsigned int maxsize = 0;
for (limitlist::iterator it = chanlimits.begin(); it != chanlimits.end(); it++)
{
if (match(channel->name, it->mask.c_str()))
{
// We have a pattern matching the channel...
maxsize = el->size();
if (maxsize < it->limit)
{
/* Ok, it *could* be allowed, now give someone subclassing us
* a chance to validate the parameter.
* The param is passed by reference, so they can both modify it
* and tell us if we allow it or not.
*
* eg, the subclass could:
* 1) allow
* 2) 'fix' parameter and then allow
* 3) deny
*/
if (ValidateParam(source, channel, parameter))
{
// And now add the mask onto the list...
ListItem e;
e.mask = assign(parameter);
e.nick = source->nick;
e.time = stringtime();
el->push_back(e);
return MODEACTION_ALLOW;
}
else
{
/* If they deny it they have the job of giving an error message */
return MODEACTION_DENY;
}
}
}
}
/* List is full, give subclass a chance to send a custom message */
if (!TellListTooLong(source, channel, parameter))
{
source->WriteServ("478 %s %s %s :Channel ban/ignore list is full", source->nick, channel->name, parameter.c_str());
}
parameter = "";
return MODEACTION_DENY;
}
else
{
// We're taking the mode off
if (el)
{
for (modelist::iterator it = el->begin(); it != el->end(); it++)
{
if (parameter == it->mask)
{
el->erase(it);
if (el->size() == 0)
{
channel->Shrink(infokey);
delete el;
}
return MODEACTION_ALLOW;
}
}
/* Tried to remove something that wasn't set */
TellNotSet(source, channel, parameter);
parameter = "";
return MODEACTION_DENY;
}
else
{
/* Hmm, taking an exception off a non-existant list, DIE */
TellNotSet(source, channel, parameter);
parameter = "";
return MODEACTION_DENY;
}
}
return MODEACTION_DENY;
}
/** Get Extensible key for this mode
*/
virtual std::string& GetInfoKey()
{
return infokey;
}
/** Handle channel deletion.
* See modules.h.
* @param chan Channel being deleted
*/
virtual void DoChannelDelete(chanrec* chan)
{
modelist* list;
chan->GetExt(infokey, list);
if (list)
{
chan->Shrink(infokey);
delete list;
}
}
/** Syncronize channel item list with another server.
* See modules.h
* @param chan Channel to syncronize
* @param proto Protocol module pointer
* @param opaque Opaque connection handle
*/
virtual void DoSyncChannel(chanrec* chan, Module* proto, void* opaque)
{
modelist* list;
chan->GetExt(infokey, list);
irc::modestacker modestack(true);
std::deque<std::string> stackresult;
if (list)
{
for (modelist::iterator it = list->begin(); it != list->end(); it++)
{
modestack.Push(std::string(1, mode)[0], assign(it->mask));
}
}
while (modestack.GetStackedLine(stackresult))
{
irc::stringjoiner mode_join(" ", stackresult, 0, stackresult.size() - 1);
std::string line = mode_join.GetJoined();
proto->ProtoSendMode(opaque, TYPE_CHANNEL, chan, line);
}
}
/** Clean up module on unload
* @param target_type Type of target to clean
* @param item Item to clean
*/
virtual void DoCleanup(int target_type, void* item)
{
}
/** Validate parameters.
* Overridden by implementing module.
* @param source Source user adding the parameter
* @param channel Channel the parameter is being added to
* @param parameter The actual parameter being added
* @return true if the parameter is valid
*/
virtual bool ValidateParam(userrec* source, chanrec* channel, std::string ¶meter)
{
return true;
}
/** Tell the user the list is too long.
* Overridden by implementing module.
* @param source Source user adding the parameter
* @param channel Channel the parameter is being added to
* @param parameter The actual parameter being added
* @return Ignored
*/
virtual bool TellListTooLong(userrec* source, chanrec* channel, std::string ¶meter)
{
return false;
}
/** Tell the user an item is already on the list.
* Overridden by implementing module.
* @param source Source user adding the parameter
* @param channel Channel the parameter is being added to
* @param parameter The actual parameter being added
*/
virtual void TellAlreadyOnList(userrec* source, chanrec* channel, std::string ¶meter)
{
}
/** Tell the user that the parameter is not in the list.
* Overridden by implementing module.
* @param source Source user removing the parameter
* @param channel Channel the parameter is being removed from
* @param parameter The actual parameter being removed
*/
virtual void TellNotSet(userrec* source, chanrec* channel, std::string ¶meter)
{
}
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef INSPIRCD_LISTMODE_PROVIDER +#define INSPIRCD_LISTMODE_PROVIDER + +#include <stdio.h> +#include <string> +#include <sstream> +#include <vector> +#include "users.h" +#include "channels.h" +#include "modules.h" +#include "wildcard.h" +#include "inspircd.h" + +/* Updated to use the <banlist> config tag if it exists + * Written by Om <omster@gmail.com>, December 2005. + * Based on code previously written by Om - April 2005 + * Updated to new API July 8th 2006 by Brain + * Originally based on m_chanprotect and m_silence + */ + +/** Get the time as a string + */ +inline std::string stringtime() +{ + std::ostringstream TIME; + TIME << time(NULL); + return TIME.str(); +} + +/** An item in a listmode's list + */ +class ListItem : public classbase +{ +public: + std::string nick; + irc::string mask; + std::string time; +}; + +/** The number of items a listmode's list may contain + */ +class ListLimit : public classbase +{ +public: + std::string mask; + unsigned int limit; +}; + +/** Items stored in the channel's list + */ +typedef std::vector<ListItem> modelist; +/** Max items per channel by name + */ +typedef std::vector<ListLimit> limitlist; + +/** A request used to check if a user is on a channel's list or not + */ +class ListModeRequest : public Request +{ + public: + userrec* user; + chanrec* chan; + + /** Check if a user is on a channel's list. + * The Event::Send() event returns true if the user is on the channel's list. + * @param sender Sending module + * @param target Target module + * @param u User to check against + * @param c Channel to check against + */ + ListModeRequest(Module* sender, Module* target, userrec* u, chanrec* c) : Request(sender, target, "LM_CHECKLIST"), user(u), chan(c) + { + } + + /** Destructor + */ + ~ListModeRequest() + { + } +}; + +/** The base class for list modes, should be inherited. + */ +class ListModeBase : public ModeHandler +{ + protected: + /** Storage key + */ + std::string infokey; + /** Numeric to use when outputting the list + */ + std::string listnumeric; + /** Numeric to indicate end of list + */ + std::string endoflistnumeric; + /** String to send for end of list + */ + std::string endofliststring; + /** Automatically tidy up entries + */ + bool tidy; + /** Config tag to check for max items per channel + */ + std::string configtag; + /** Limits on a per-channel basis read from the tag + * specified in ListModeBase::configtag + */ + limitlist chanlimits; + + public: + /** Constructor. + * @param Instance The creator of this class + * @param modechar Mode character + * @param eolstr End of list string + * @pram lnum List numeric + * @param eolnum End of list numeric + * @param autotidy Automatically tidy list entries on add + * @param ctag Configuration tag to get limits from + */ + ListModeBase(InspIRCd* Instance, char modechar, const std::string &eolstr, const std::string &lnum, const std::string &eolnum, bool autotidy, const std::string &ctag = "banlist") + : ModeHandler(Instance, modechar, 1, 1, true, MODETYPE_CHANNEL, false), listnumeric(lnum), endoflistnumeric(eolnum), endofliststring(eolstr), tidy(autotidy), configtag(ctag) + { + this->DoRehash(); + infokey = "listbase_mode_" + std::string(1, mode) + "_list"; + } + + /** See mode.h + */ + std::pair<bool,std::string> ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter) + { + modelist* el; + channel->GetExt(infokey, el); + if (el) + { + for (modelist::iterator it = el->begin(); it != el->end(); it++) + { + if(parameter == it->mask) + { + return std::make_pair(true, parameter); + } + } + } + return std::make_pair(false, parameter); + } + + /** Display the list for this mode + * @param user The user to send the list to + * @param channel The channel the user is requesting the list for + */ + virtual void DisplayList(userrec* user, chanrec* channel) + { + modelist* el; + channel->GetExt(infokey, el); + if (el) + { + for (modelist::reverse_iterator it = el->rbegin(); it != el->rend(); ++it) + { + user->WriteServ("%s %s %s %s %s %s", listnumeric.c_str(), user->nick, channel->name, it->mask.c_str(), it->nick.c_str(), it->time.c_str()); + } + } + user->WriteServ("%s %s %s :%s", endoflistnumeric.c_str(), user->nick, channel->name, endofliststring.c_str()); + } + + /** Remove all instances of the mode from a channel. + * See mode.h + * @param channel The channel to remove all instances of the mode from + */ + virtual void RemoveMode(chanrec* channel) + { + modelist* el; + channel->GetExt(infokey, el); + if (el) + { + irc::modestacker modestack(false); + std::deque<std::string> stackresult; + const char* mode_junk[MAXMODES+2]; + mode_junk[0] = channel->name; + userrec* n = new userrec(ServerInstance); + n->SetFd(FD_MAGIC_NUMBER); + for (modelist::iterator it = el->begin(); it != el->end(); it++) + { + modestack.Push(this->GetModeChar(), assign(it->mask)); + } + while (modestack.GetStackedLine(stackresult)) + { + for (size_t j = 0; j < stackresult.size(); j++) + { + mode_junk[j+1] = stackresult[j].c_str(); + } + ServerInstance->SendMode(mode_junk, stackresult.size() + 1, n); + } + + delete n; + } + } + + /** See mode.h + */ + virtual void RemoveMode(userrec* user) + { + /* Listmodes dont get set on users */ + } + + /** Perform a rehash of this mode's configuration data + */ + virtual void DoRehash() + { + ConfigReader Conf(ServerInstance); + + chanlimits.clear(); + + for (int i = 0; i < Conf.Enumerate(configtag); i++) + { + // For each <banlist> tag + ListLimit limit; + limit.mask = Conf.ReadValue(configtag, "chan", i); + limit.limit = Conf.ReadInteger(configtag, "limit", i, true); + + if (limit.mask.size() && limit.limit > 0) + chanlimits.push_back(limit); + } + if (chanlimits.size() == 0) + { + ListLimit limit; + limit.mask = "*"; + limit.limit = 64; + chanlimits.push_back(limit); + } + } + + /** Populate the Implements list with the correct events for a List Mode + */ + virtual void DoImplements(char* List) + { + List[I_OnChannelDelete] = List[I_OnSyncChannel] = List[I_OnCleanup] = List[I_OnRehash] = 1; + } + + /** Handle the list mode. + * See mode.h + */ + virtual ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding) + { + // Try and grab the list + modelist* el; + channel->GetExt(infokey, el); + + if (adding) + { + // If there was no list + if (!el) + { + // Make one + el = new modelist; + channel->Extend(infokey, el); + } + + // Clean the mask up + if (this->tidy) + ModeParser::CleanMask(parameter); + + // Check if the item already exists in the list + for (modelist::iterator it = el->begin(); it != el->end(); it++) + { + if (parameter == it->mask) + { + /* Give a subclass a chance to error about this */ + TellAlreadyOnList(source, channel, parameter); + + // it does, deny the change + return MODEACTION_DENY; + } + } + + unsigned int maxsize = 0; + + for (limitlist::iterator it = chanlimits.begin(); it != chanlimits.end(); it++) + { + if (match(channel->name, it->mask.c_str())) + { + // We have a pattern matching the channel... + maxsize = el->size(); + if (maxsize < it->limit) + { + /* Ok, it *could* be allowed, now give someone subclassing us + * a chance to validate the parameter. + * The param is passed by reference, so they can both modify it + * and tell us if we allow it or not. + * + * eg, the subclass could: + * 1) allow + * 2) 'fix' parameter and then allow + * 3) deny + */ + if (ValidateParam(source, channel, parameter)) + { + // And now add the mask onto the list... + ListItem e; + e.mask = assign(parameter); + e.nick = source->nick; + e.time = stringtime(); + + el->push_back(e); + return MODEACTION_ALLOW; + } + else + { + /* If they deny it they have the job of giving an error message */ + return MODEACTION_DENY; + } + } + } + } + + /* List is full, give subclass a chance to send a custom message */ + if (!TellListTooLong(source, channel, parameter)) + { + source->WriteServ("478 %s %s %s :Channel ban/ignore list is full", source->nick, channel->name, parameter.c_str()); + } + + parameter = ""; + return MODEACTION_DENY; + } + else + { + // We're taking the mode off + if (el) + { + for (modelist::iterator it = el->begin(); it != el->end(); it++) + { + if (parameter == it->mask) + { + el->erase(it); + if (el->size() == 0) + { + channel->Shrink(infokey); + delete el; + } + return MODEACTION_ALLOW; + } + } + /* Tried to remove something that wasn't set */ + TellNotSet(source, channel, parameter); + parameter = ""; + return MODEACTION_DENY; + } + else + { + /* Hmm, taking an exception off a non-existant list, DIE */ + TellNotSet(source, channel, parameter); + parameter = ""; + return MODEACTION_DENY; + } + } + return MODEACTION_DENY; + } + + /** Get Extensible key for this mode + */ + virtual std::string& GetInfoKey() + { + return infokey; + } + + /** Handle channel deletion. + * See modules.h. + * @param chan Channel being deleted + */ + virtual void DoChannelDelete(chanrec* chan) + { + modelist* list; + chan->GetExt(infokey, list); + + if (list) + { + chan->Shrink(infokey); + delete list; + } + } + + /** Syncronize channel item list with another server. + * See modules.h + * @param chan Channel to syncronize + * @param proto Protocol module pointer + * @param opaque Opaque connection handle + */ + virtual void DoSyncChannel(chanrec* chan, Module* proto, void* opaque) + { + modelist* list; + chan->GetExt(infokey, list); + irc::modestacker modestack(true); + std::deque<std::string> stackresult; + if (list) + { + for (modelist::iterator it = list->begin(); it != list->end(); it++) + { + modestack.Push(std::string(1, mode)[0], assign(it->mask)); + } + } + while (modestack.GetStackedLine(stackresult)) + { + irc::stringjoiner mode_join(" ", stackresult, 0, stackresult.size() - 1); + std::string line = mode_join.GetJoined(); + proto->ProtoSendMode(opaque, TYPE_CHANNEL, chan, line); + } + } + + /** Clean up module on unload + * @param target_type Type of target to clean + * @param item Item to clean + */ + virtual void DoCleanup(int target_type, void* item) + { + } + + /** Validate parameters. + * Overridden by implementing module. + * @param source Source user adding the parameter + * @param channel Channel the parameter is being added to + * @param parameter The actual parameter being added + * @return true if the parameter is valid + */ + virtual bool ValidateParam(userrec* source, chanrec* channel, std::string ¶meter) + { + return true; + } + + /** Tell the user the list is too long. + * Overridden by implementing module. + * @param source Source user adding the parameter + * @param channel Channel the parameter is being added to + * @param parameter The actual parameter being added + * @return Ignored + */ + virtual bool TellListTooLong(userrec* source, chanrec* channel, std::string ¶meter) + { + return false; + } + + /** Tell the user an item is already on the list. + * Overridden by implementing module. + * @param source Source user adding the parameter + * @param channel Channel the parameter is being added to + * @param parameter The actual parameter being added + */ + virtual void TellAlreadyOnList(userrec* source, chanrec* channel, std::string ¶meter) + { + } + + /** Tell the user that the parameter is not in the list. + * Overridden by implementing module. + * @param source Source user removing the parameter + * @param channel Channel the parameter is being removed from + * @param parameter The actual parameter being removed + */ + virtual void TellNotSet(userrec* source, chanrec* channel, std::string ¶meter) + { + } +}; + +#endif + diff --git a/include/users.h b/include/users.h index 7420cc42f..0443b24d2 100644 --- a/include/users.h +++ b/include/users.h @@ -1 +1,1031 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __USERS_H__
#define __USERS_H__
#include <string>
#include "inspircd_config.h"
#include "socket.h"
#include "channels.h"
#include "inspstring.h"
#include "connection.h"
#include "hashcomp.h"
#include "dns.h"
/** Channel status for a user
*/
enum ChanStatus {
/** Op */
STATUS_OP = 4,
/** Halfop */
STATUS_HOP = 2,
/** Voice */
STATUS_VOICE = 1,
/** None */
STATUS_NORMAL = 0
};
/** connect class types
*/
enum ClassTypes {
/** connect:allow */
CC_ALLOW = 0,
/** connect:deny */
CC_DENY = 1
};
/** RFC1459 channel modes
*/
enum UserModes {
/** +s: Server notices */
UM_SERVERNOTICE = 's' - 65,
/** +w: WALLOPS */
UM_WALLOPS = 'w' - 65,
/** +i: Invisible */
UM_INVISIBLE = 'i' - 65,
/** +o: Operator */
UM_OPERATOR = 'o' - 65,
/** +n: Server notice mask */
UM_SNOMASK = 'n' - 65
};
/** Registration state of a user, e.g.
* have they sent USER, NICK, PASS yet?
*/
enum RegistrationState {
#ifndef WIN32 // Burlex: This is already defined in win32, luckily it is still 0.
REG_NONE = 0, /* Has sent nothing */
#endif
REG_USER = 1, /* Has sent USER */
REG_NICK = 2, /* Has sent NICK */
REG_NICKUSER = 3, /* Bitwise combination of REG_NICK and REG_USER */
REG_ALL = 7 /* REG_NICKUSER plus next bit along */
};
/* Required forward declaration */
class InspIRCd;
/** Derived from Resolver, and performs user forward/reverse lookups.
*/
class CoreExport UserResolver : public Resolver
{
private:
/** User this class is 'attached' to.
*/
userrec* bound_user;
/** File descriptor teh lookup is bound to
*/
int bound_fd;
/** True if the lookup is forward, false if is a reverse lookup
*/
bool fwd;
public:
/** Create a resolver.
* @param Instance The creating instance
* @param user The user to begin lookup on
* @param to_resolve The IP or host to resolve
* @param qt The query type
* @param cache Modified by the constructor if the result was cached
*/
UserResolver(InspIRCd* Instance, userrec* user, std::string to_resolve, QueryType qt, bool &cache);
/** Called on successful lookup
* @param result Result string
* @param ttl Time to live for result
* @param cached True if the result was found in the cache
*/
void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached);
/** Called on failed lookup
* @param e Error code
* @param errormessage Error message string
*/
void OnError(ResolverError e, const std::string &errormessage);
};
/** Holds information relevent to <connect allow> and <connect deny> tags in the config file.
*/
class CoreExport ConnectClass : public classbase
{
private:
/** Type of line, either CC_ALLOW or CC_DENY
*/
char type;
/** Max time to register the connection in seconds
*/
unsigned int registration_timeout;
/** Number of lines in buffer before excess flood is triggered
*/
unsigned int flood;
/** Host mask for this line
*/
std::string host;
/** Number of seconds between pings for this line
*/
unsigned int pingtime;
/** (Optional) Password for this line
*/
std::string pass;
/** Threshold value for flood disconnect
*/
unsigned int threshold;
/** Maximum size of sendq for users in this class (bytes)
*/
unsigned long sendqmax;
/** Maximum size of recvq for users in this class (bytes)
*/
unsigned long recvqmax;
/** Local max when connecting by this connection class
*/
unsigned long maxlocal;
/** Global max when connecting by this connection class
*/
unsigned long maxglobal;
/** Port number this connect class applies to
*/
int port;
public:
/** Create a new connect class with no settings.
*/
ConnectClass() : type(CC_DENY), registration_timeout(0), flood(0), host(""), pingtime(0), pass(""),
threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0) { }
/** Create a new connect class to ALLOW connections.
* @param timeout The registration timeout
* @param fld The flood value
* @param hst The IP mask to allow
* @param ping The ping frequency
* @param pas The password to be used
* @param thres The flooding threshold
* @param sendq The maximum sendq value
* @param recvq The maximum recvq value
* @param maxl The maximum local sessions
* @param maxg The maximum global sessions
*/
ConnectClass(unsigned int timeout, unsigned int fld, const std::string &hst, unsigned int ping,
const std::string &pas, unsigned int thres, unsigned long sendq, unsigned long recvq,
unsigned long maxl, unsigned long maxg, int p = 0) :
type(CC_ALLOW), registration_timeout(timeout), flood(fld), host(hst), pingtime(ping), pass(pas),
threshold(thres), sendqmax(sendq), recvqmax(recvq), maxlocal(maxl), maxglobal(maxg), port(p) { }
/** Create a new connect class to DENY connections
* @param hst The IP mask to deny
*/
ConnectClass(const std::string &hst) : type(CC_DENY), registration_timeout(0), flood(0), host(hst), pingtime(0),
pass(""), threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0), port(0) { }
/** Returns the type, CC_ALLOW or CC_DENY
*/
char GetType()
{
return (type == CC_ALLOW ? CC_ALLOW : CC_DENY);
}
/** Returns the registration timeout
*/
unsigned int GetRegTimeout()
{
return (registration_timeout ? registration_timeout : 90);
}
/** Returns the flood limit
*/
unsigned int GetFlood()
{
return (threshold ? flood : 999);
}
/** Returns the allowed or denied IP mask
*/
const std::string& GetHost()
{
return host;
}
int GetPort()
{
return port;
}
/** Returns the ping frequency
*/
unsigned int GetPingTime()
{
return (pingtime ? pingtime : 120);
}
/** Returns the password or an empty string
*/
const std::string& GetPass()
{
return pass;
}
/** Returns the flood threshold value
*/
unsigned int GetThreshold()
{
return (threshold ? threshold : 1);
}
/** Returns the maximum sendq value
*/
unsigned long GetSendqMax()
{
return (sendqmax ? sendqmax : 262114);
}
/** Returns the maximum recvq value
*/
unsigned long GetRecvqMax()
{
return (recvqmax ? recvqmax : 4096);
}
/** Returusn the maximum number of local sessions
*/
unsigned long GetMaxLocal()
{
return maxlocal;
}
/** Returns the maximum number of global sessions
*/
unsigned long GetMaxGlobal()
{
return maxglobal;
}
};
/** Holds a complete list of all channels to which a user has been invited and has not yet joined.
*/
typedef std::vector<irc::string> InvitedList;
/** Holds a complete list of all allow and deny tags from the configuration file (connection classes)
*/
typedef std::vector<ConnectClass> ClassVector;
/** Typedef for the list of user-channel records for a user
*/
typedef std::map<chanrec*, char> UserChanList;
/** Shorthand for an iterator into a UserChanList
*/
typedef UserChanList::iterator UCListIter;
/* Required forward declaration
*/
class userrec;
/** Visibility data for a user.
* If a user has a non-null instance of this class in their userrec,
* then it is used to determine if this user is visible to other users
* or not.
*/
class CoreExport VisData
{
public:
/** Create a visdata
*/
VisData();
/** Destroy a visdata
*/
virtual ~VisData();
/** Is this user visible to some other user?
* @param user The other user to compare to
* @return true True if the user is visible to the other user, false if not
*/
virtual bool VisibleTo(userrec* user);
};
/** Holds all information about a user
* This class stores all information about a user connected to the irc server. Everything about a
* connection is stored here primarily, from the user's socket ID (file descriptor) through to the
* user's nickname and hostname. Use the FindNick method of the InspIRCd class to locate a specific user
* by nickname, or the FindDescriptor method of the InspIRCd class to find a specific user by their
* file descriptor value.
*/
class CoreExport userrec : public connection
{
private:
/** Pointer to creator.
* This is required to make use of core functions
* from within the userrec class.
*/
InspIRCd* ServerInstance;
/** A list of channels the user has a pending invite to.
* Upon INVITE channels are added, and upon JOIN, the
* channels are removed from this list.
*/
InvitedList invites;
/** Number of channels this user is currently on
*/
unsigned int ChannelCount;
/** Cached nick!ident@host value using the real hostname
*/
char* cached_fullhost;
/** Cached nick!ident@ip value using the real IP address
*/
char* cached_hostip;
/** Cached nick!ident@host value using the masked hostname
*/
char* cached_makehost;
/** Cached nick!ident@realhost value using the real hostname
*/
char* cached_fullrealhost;
/** When we erase the user (in the destructor),
* we call this method to subtract one from all
* mode characters this user is making use of.
*/
void DecrementModes();
/** Oper-only quit message for this user if non-null
*/
char* operquit;
public:
/** Resolvers for looking up this users IP address
* This will occur if and when res_reverse completes.
* When this class completes its lookup, userrec::dns_done
* will be set from false to true.
*/
UserResolver* res_forward;
/** Resolvers for looking up this users hostname
* This is instantiated by userrec::StartDNSLookup(),
* and on success, instantiates userrec::res_reverse.
*/
UserResolver* res_reverse;
/** User visibility state, see definition of VisData.
*/
VisData* Visibility;
/** Stored reverse lookup from res_forward
*/
std::string stored_host;
/** Starts a DNS lookup of the user's IP.
* This will cause two UserResolver classes to be instantiated.
* When complete, these objects set userrec::dns_done to true.
*/
void StartDNSLookup();
/** The users nickname.
* An invalid nickname indicates an unregistered connection prior to the NICK command.
* Use InspIRCd::IsNick() to validate nicknames.
*/
char nick[NICKMAX];
/** The users ident reply.
* Two characters are added to the user-defined limit to compensate for the tilde etc.
*/
char ident[IDENTMAX+2];
/** The host displayed to non-opers (used for cloaking etc).
* This usually matches the value of userrec::host.
*/
char dhost[65];
/** The users full name (GECOS).
*/
char fullname[MAXGECOS+1];
/** The user's mode list.
* This is NOT a null terminated string! In the 1.1 version of InspIRCd
* this is an array of values in a similar way to channel modes.
* A value of 1 in field (modeletter-65) indicates that the mode is
* set, for example, to work out if mode +s is set, we check the field
* userrec::modes['s'-65] != 0.
* The following RFC characters o, w, s, i have constants defined via an
* enum, such as UM_SERVERNOTICE and UM_OPETATOR.
*/
char modes[64];
/** What snomasks are set on this user.
* This functions the same as the above modes.
*/
char snomasks[64];
/** Channels this user is on, and the permissions they have there
*/
UserChanList chans;
/** The server the user is connected to.
*/
const char* server;
/** The user's away message.
* If this string is empty, the user is not marked as away.
*/
char awaymsg[MAXAWAY+1];
/** Number of lines the user can place into the buffer
* (up to the global NetBufferSize bytes) before they
* are disconnected for excess flood
*/
int flood;
/** Timestamp of current time + connection class timeout.
* This user must send USER/NICK before this timestamp is
* reached or they will be disconnected.
*/
time_t timeout;
/** The oper type they logged in as, if they are an oper.
* This is used to check permissions in operclasses, so that
* we can say 'yay' or 'nay' to any commands they issue.
* The value of this is the value of a valid 'type name=' tag.
*/
char oper[NICKMAX];
/** True when DNS lookups are completed.
* The UserResolver classes res_forward and res_reverse will
* set this value once they complete.
*/
bool dns_done;
/** Number of seconds between PINGs for this user (set from <connect:allow> tag
*/
unsigned int pingmax;
/** Password specified by the user when they registered.
* This is stored even if the <connect> block doesnt need a password, so that
* modules may check it.
*/
char password[64];
/** User's receive queue.
* Lines from the IRCd awaiting processing are stored here.
* Upgraded april 2005, old system a bit hairy.
*/
std::string recvq;
/** User's send queue.
* Lines waiting to be sent are stored here until their buffer is flushed.
*/
std::string sendq;
/** Flood counters - lines received
*/
int lines_in;
/** Flood counters - time lines_in is due to be reset
*/
time_t reset_due;
/** Flood counters - Highest value lines_in may reach before the user gets disconnected
*/
long threshold;
/** If this is set to true, then all read operations for the user
* are dropped into the bit-bucket.
* This is used by the global CullList, but please note that setting this value
* alone will NOT cause the user to quit. This means it can be used seperately,
* for example by shun modules etc.
*/
bool muted;
/** IPV4 or IPV6 ip address. Use SetSockAddr to set this and GetProtocolFamily/
* GetIPString/GetPort to obtain its values.
*/
sockaddr* ip;
/** Initialize the clients sockaddr
* @param protocol_family The protocol family of the IP address, AF_INET or AF_INET6
* @param ip A human-readable IP address for this user matching the protcol_family
* @param port The port number of this user or zero for a remote user
*/
void SetSockAddr(int protocol_family, const char* ip, int port);
/** Get port number from sockaddr
* @return The port number of this user.
*/
int GetPort();
/** Get protocol family from sockaddr
* @return The protocol family of this user, either AF_INET or AF_INET6
*/
int GetProtocolFamily();
/** Get IP string from sockaddr, using static internal buffer
* @return The IP string
*/
const char* GetIPString();
/** Get IP string from sockaddr, using caller-specified buffer
* @param buf A buffer to use
* @return The IP string
*/
const char* GetIPString(char* buf);
/* Write error string
*/
std::string WriteError;
/** Maximum size this user's sendq can become.
* Copied from the connect class on connect.
*/
long sendqmax;
/** Maximum size this user's recvq can become.
* Copied from the connect class on connect.
*/
long recvqmax;
/** This is true if the user matched an exception when they connected to the ircd.
* It isnt valid after this point, and you should not attempt to do anything with it
* after this point, because the eline might be removed at a later time, and/or no
* longer be applicable to this user. It is only used to save doing the eline lookup
* twice (instead we do it once and set this value).
*/
bool exempt;
/** Default constructor
* @throw Nothing at present
*/
userrec(InspIRCd* Instance);
/** Returns the full displayed host of the user
* This member function returns the hostname of the user as seen by other users
* on the server, in nick!ident&at;host form.
* @return The full masked host of the user
*/
virtual char* GetFullHost();
/** Returns the full real host of the user
* This member function returns the hostname of the user as seen by other users
* on the server, in nick!ident&at;host form. If any form of hostname cloaking is in operation,
* e.g. through a module, then this method will ignore it and return the true hostname.
* @return The full real host of the user
*/
virtual char* GetFullRealHost();
/** This clears any cached results that are used for GetFullRealHost() etc.
* The results of these calls are cached as generating them can be generally expensive.
*/
void InvalidateCache();
/** Create a displayable mode string for this users snomasks
* @return The notice mask character sequence
*/
const char* FormatNoticeMasks();
/** Process a snomask modifier string, e.g. +abc-de
* @param sm A sequence of notice mask characters
* @return The cleaned mode sequence which can be output,
* e.g. in the above example if masks c and e are not
* valid, this function will return +ab-d
*/
std::string ProcessNoticeMasks(const char *sm);
/** Returns true if a notice mask is set
* @param sm A notice mask character to check
* @return True if the notice mask is set
*/
bool IsNoticeMaskSet(unsigned char sm);
/** Changed a specific notice mask value
* @param sm The server notice mask to change
* @param value An on/off value for this mask
*/
void SetNoticeMask(unsigned char sm, bool value);
/** Create a displayable mode string for this users umodes
* @param The mode string
*/
const char* FormatModes();
/** Returns true if a specific mode is set
* @param m The user mode
* @return True if the mode is set
*/
bool IsModeSet(unsigned char m);
/** Set a specific usermode to on or off
* @param m The user mode
* @param value On or off setting of the mode
*/
void SetMode(unsigned char m, bool value);
/** Returns true if a user is invited to a channel.
* @param channel A channel name to look up
* @return True if the user is invited to the given channel
*/
virtual bool IsInvited(const irc::string &channel);
/** Adds a channel to a users invite list (invites them to a channel)
* @param channel A channel name to add
*/
virtual void InviteTo(const irc::string &channel);
/** Removes a channel from a users invite list.
* This member function is called on successfully joining an invite only channel
* to which the user has previously been invited, to clear the invitation.
* @param channel The channel to remove the invite to
*/
virtual void RemoveInvite(const irc::string &channel);
/** Returns true or false for if a user can execute a privilaged oper command.
* This is done by looking up their oper type from userrec::oper, then referencing
* this to their oper classes and checking the commands they can execute.
* @param command A command (should be all CAPS)
* @return True if this user can execute the command
*/
bool HasPermission(const std::string &command);
/** Calls read() to read some data for this user using their fd.
* @param buffer The buffer to read into
* @param size The size of data to read
* @return The number of bytes read, or -1 if an error occured.
*/
int ReadData(void* buffer, size_t size);
/** This method adds data to the read buffer of the user.
* The buffer can grow to any size within limits of the available memory,
* managed by the size of a std::string, however if any individual line in
* the buffer grows over 600 bytes in length (which is 88 chars over the
* RFC-specified limit per line) then the method will return false and the
* text will not be inserted.
* @param a The string to add to the users read buffer
* @return True if the string was successfully added to the read buffer
*/
bool AddBuffer(std::string a);
/** This method returns true if the buffer contains at least one carriage return
* character (e.g. one complete line may be read)
* @return True if there is at least one complete line in the users buffer
*/
bool BufferIsReady();
/** This function clears the entire buffer by setting it to an empty string.
*/
void ClearBuffer();
/** This method returns the first available string at the tail end of the buffer
* and advances the tail end of the buffer past the string. This means it is
* a one way operation in a similar way to strtok(), and multiple calls return
* multiple lines if they are available. The results of this function if there
* are no lines to be read are unknown, always use BufferIsReady() to check if
* it is ok to read the buffer before calling GetBuffer().
* @return The string at the tail end of this users buffer
*/
std::string GetBuffer();
/** Sets the write error for a connection. This is done because the actual disconnect
* of a client may occur at an inopportune time such as half way through /LIST output.
* The WriteErrors of clients are checked at a more ideal time (in the mainloop) and
* errored clients purged.
* @param error The error string to set.
*/
void SetWriteError(const std::string &error);
/** Returns the write error which last occured on this connection or an empty string
* if none occured.
* @return The error string which has occured for this user
*/
const char* GetWriteError();
/** Adds to the user's write buffer.
* You may add any amount of text up to this users sendq value, if you exceed the
* sendq value, SetWriteError() will be called to set the users error string to
* "SendQ exceeded", and further buffer adds will be dropped.
* @param data The data to add to the write buffer
*/
void AddWriteBuf(const std::string &data);
/** Flushes as much of the user's buffer to the file descriptor as possible.
* This function may not always flush the entire buffer, rather instead as much of it
* as it possibly can. If the send() call fails to send the entire buffer, the buffer
* position is advanced forwards and the rest of the data sent at the next call to
* this method.
*/
void FlushWriteBuf();
/** Returns the list of channels this user has been invited to but has not yet joined.
* @return A list of channels the user is invited to
*/
InvitedList* GetInviteList();
/** Creates a wildcard host.
* Takes a buffer to use and fills the given buffer with the host in the format *!*@hostname
* @return The wildcarded hostname in *!*@host form
*/
char* MakeWildHost();
/** Creates a usermask with real host.
* Takes a buffer to use and fills the given buffer with the hostmask in the format user@host
* @return the usermask in the format user@host
*/
char* MakeHost();
/** Creates a usermask with real ip.
* Takes a buffer to use and fills the given buffer with the ipmask in the format user@ip
* @return the usermask in the format user@ip
*/
char* MakeHostIP();
/** Shuts down and closes the user's socket
* This will not cause the user to be deleted. Use InspIRCd::QuitUser for this,
* which will call CloseSocket() for you.
*/
void CloseSocket();
/** Disconnect a user gracefully
* @param user The user to remove
* @param r The quit reason to show to normal users
* @param oreason The quit reason to show to opers
* @return Although this function has no return type, on exit the user provided will no longer exist.
*/
static void QuitUser(InspIRCd* Instance, userrec *user, const std::string &r, const char* oreason = "");
/** Add the user to WHOWAS system
*/
void AddToWhoWas();
/** Oper up the user using the given opertype.
* This will also give the +o usermode.
* @param opertype The oper type to oper as
*/
void Oper(const std::string &opertype);
/** Call this method to find the matching <connect> for a user, and to check them against it.
*/
void CheckClass();
/** Use this method to fully connect a user.
* This will send the message of the day, check G/K/E lines, etc.
*/
void FullConnect();
/** Change this users hash key to a new string.
* You should not call this function directly. It is used by the core
* to update the users hash entry on a nickchange.
* @param New new user_hash key
* @return Pointer to userrec in hash (usually 'this')
*/
userrec* UpdateNickHash(const char* New);
/** Force a nickname change.
* If the nickname change fails (for example, because the nick in question
* already exists) this function will return false, and you must then either
* output an error message, or quit the user for nickname collision.
* @param newnick The nickname to change to
* @return True if the nickchange was successful.
*/
bool ForceNickChange(const char* newnick);
/** Add a client to the system.
* This will create a new userrec, insert it into the user_hash,
* initialize it as not yet registered, and add it to the socket engine.
* @param Instance a pointer to the server instance
* @param socket The socket id (file descriptor) this user is on
* @param port The port number this user connected on
* @param iscached This variable is reserved for future use
* @param ip The IP address of the user
* @return This function has no return value, but a call to AddClient may remove the user.
*/
static void AddClient(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip);
/** Oper down.
* This will clear the +o usermode and unset the user's oper type
*/
void UnOper();
/** Return the number of global clones of this user
* @return The global clone count of this user
*/
unsigned long GlobalCloneCount();
/** Return the number of local clones of this user
* @return The local clone count of this user
*/
unsigned long LocalCloneCount();
/** Remove all clone counts from the user, you should
* use this if you change the user's IP address in
* userrec::ip after they have registered.
*/
void RemoveCloneCounts();
/** Write text to this user, appending CR/LF.
* @param text A std::string to send to the user
*/
void Write(std::string text);
/** Write text to this user, appending CR/LF.
* @param text The format string for text to send to the user
* @param ... POD-type format arguments
*/
void Write(const char *text, ...);
/** Write text to this user, appending CR/LF and prepending :server.name
* @param text A std::string to send to the user
*/
void WriteServ(const std::string& text);
/** Write text to this user, appending CR/LF and prepending :server.name
* @param text The format string for text to send to the user
* @param ... POD-type format arguments
*/
void WriteServ(const char* text, ...);
/** Write text to this user, appending CR/LF and prepending :nick!user@host of the user provided in the first parameter.
* @param user The user to prepend the :nick!user@host of
* @param text A std::string to send to the user
*/
void WriteFrom(userrec *user, const std::string &text);
/** Write text to this user, appending CR/LF and prepending :nick!user@host of the user provided in the first parameter.
* @param user The user to prepend the :nick!user@host of
* @param text The format string for text to send to the user
* @param ... POD-type format arguments
*/
void WriteFrom(userrec *user, const char* text, ...);
/** Write text to the user provided in the first parameter, appending CR/LF, and prepending THIS user's :nick!user@host.
* @param dest The user to route the message to
* @param text A std::string to send to the user
*/
void WriteTo(userrec *dest, const std::string &data);
/** Write text to the user provided in the first parameter, appending CR/LF, and prepending THIS user's :nick!user@host.
* @param dest The user to route the message to
* @param text The format string for text to send to the user
* @param ... POD-type format arguments
*/
void WriteTo(userrec *dest, const char *data, ...);
/** Write to all users that can see this user (including this user in the list), appending CR/LF
* @param text A std::string to send to the users
*/
void WriteCommon(const std::string &text);
/** Write to all users that can see this user (including this user in the list), appending CR/LF
* @param text The format string for text to send to the users
* @param ... POD-type format arguments
*/
void WriteCommon(const char* text, ...);
/** Write to all users that can see this user (not including this user in the list), appending CR/LF
* @param text The format string for text to send to the users
* @param ... POD-type format arguments
*/
void WriteCommonExcept(const char* text, ...);
/** Write to all users that can see this user (not including this user in the list), appending CR/LF
* @param text A std::string to send to the users
*/
void WriteCommonExcept(const std::string &text);
/** Write a quit message to all common users, as in userrec::WriteCommonExcept but with a specific
* quit message for opers only.
* @param normal_text Normal user quit message
* @param oper_text Oper only quit message
*/
void WriteCommonQuit(const std::string &normal_text, const std::string &oper_text);
/** Write a WALLOPS message from this user to all local opers.
* If this user is not opered, the function will return without doing anything.
* @param text The format string to send in the WALLOPS message
* @param ... Format arguments
*/
void WriteWallOps(const char* text, ...);
/** Write a WALLOPS message from this user to all local opers.
* If this user is not opered, the function will return without doing anything.
* @param text The text to send in the WALLOPS message
*/
void WriteWallOps(const std::string &text);
/** Return true if the user shares at least one channel with another user
* @param other The other user to compare the channel list against
* @return True if the given user shares at least one channel with this user
*/
bool SharesChannelWith(userrec *other);
/** Change the displayed host of a user.
* ALWAYS use this function, rather than writing userrec::dhost directly,
* as this triggers module events allowing the change to be syncronized to
* remote servers. This will also emulate a QUIT and rejoin (where configured)
* before setting their host field.
* @param host The new hostname to set
* @return True if the change succeeded, false if it didn't
*/
bool ChangeDisplayedHost(const char* host);
/** Change the ident (username) of a user.
* ALWAYS use this function, rather than writing userrec::ident directly,
* as this correctly causes the user to seem to quit (where configured)
* before setting their ident field.
* @param host The new ident to set
* @return True if the change succeeded, false if it didn't
*/
bool ChangeIdent(const char* newident);
/** Change a users realname field.
* ALWAYS use this function, rather than writing userrec::fullname directly,
* as this triggers module events allowing the change to be syncronized to
* remote servers.
* @param gecos The user's new realname
* @return True if the change succeeded, false if otherwise
*/
bool ChangeName(const char* gecos);
/** Send a command to all local users from this user
* The command given must be able to send text with the
* first parameter as a servermask (e.g. $*), so basically
* you should use PRIVMSG or NOTICE.
* @param command the command to send
* @param text The text format string to send
* @param ... Format arguments
*/
void SendAll(const char* command, char* text, ...);
/** Compile a channel list for this user, and send it to the user 'source'
* Used internally by WHOIS
* @param The user to send the channel list to if it is not too long
* @return This user's channel list
*/
std::string ChannelList(userrec* source);
/** Split the channel list in cl which came from dest, and spool it to this user
* Used internally by WHOIS
* @param dest The user the original channel list came from
* @param cl The channel list as a string obtained from userrec::ChannelList()
*/
void SplitChanList(userrec* dest, const std::string &cl);
/** Remove this user from all channels they are on, and delete any that are now empty.
* This is used by QUIT, and will not send part messages!
*/
void PurgeEmptyChannels();
/** Get the connect class which matches this user's host or IP address
* @return A reference to this user's connect class
*/
ConnectClass* GetClass();
/** Show the message of the day to this user
*/
void ShowMOTD();
/** Show the server RULES file to this user
*/
void ShowRULES();
/** Set oper-specific quit message shown to opers only when the user quits
* (overrides any sent by QuitUser)
*/
void SetOperQuit(const std::string &oquit);
/** Get oper-specific quit message shown only to opers when the user quits.
* (overrides any sent by QuitUser)
*/
const char* GetOperQuit();
/** Handle socket event.
* From EventHandler class.
* @param et Event type
* @param errornum Error number for EVENT_ERROR events
*/
void HandleEvent(EventType et, int errornum = 0);
/** Default destructor
*/
virtual ~userrec();
};
/* Configuration callbacks */
class ServerConfig;
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __USERS_H__ +#define __USERS_H__ + +#include <string> +#include "inspircd_config.h" +#include "socket.h" +#include "channels.h" +#include "inspstring.h" +#include "connection.h" +#include "hashcomp.h" +#include "dns.h" + +/** Channel status for a user + */ +enum ChanStatus { + /** Op */ + STATUS_OP = 4, + /** Halfop */ + STATUS_HOP = 2, + /** Voice */ + STATUS_VOICE = 1, + /** None */ + STATUS_NORMAL = 0 +}; + +/** connect class types + */ +enum ClassTypes { + /** connect:allow */ + CC_ALLOW = 0, + /** connect:deny */ + CC_DENY = 1 +}; + +/** RFC1459 channel modes + */ +enum UserModes { + /** +s: Server notices */ + UM_SERVERNOTICE = 's' - 65, + /** +w: WALLOPS */ + UM_WALLOPS = 'w' - 65, + /** +i: Invisible */ + UM_INVISIBLE = 'i' - 65, + /** +o: Operator */ + UM_OPERATOR = 'o' - 65, + /** +n: Server notice mask */ + UM_SNOMASK = 'n' - 65 +}; + +/** Registration state of a user, e.g. + * have they sent USER, NICK, PASS yet? + */ +enum RegistrationState { + +#ifndef WIN32 // Burlex: This is already defined in win32, luckily it is still 0. + REG_NONE = 0, /* Has sent nothing */ +#endif + + REG_USER = 1, /* Has sent USER */ + REG_NICK = 2, /* Has sent NICK */ + REG_NICKUSER = 3, /* Bitwise combination of REG_NICK and REG_USER */ + REG_ALL = 7 /* REG_NICKUSER plus next bit along */ +}; + +/* Required forward declaration */ +class InspIRCd; + +/** Derived from Resolver, and performs user forward/reverse lookups. + */ +class CoreExport UserResolver : public Resolver +{ + private: + /** User this class is 'attached' to. + */ + userrec* bound_user; + /** File descriptor teh lookup is bound to + */ + int bound_fd; + /** True if the lookup is forward, false if is a reverse lookup + */ + bool fwd; + public: + /** Create a resolver. + * @param Instance The creating instance + * @param user The user to begin lookup on + * @param to_resolve The IP or host to resolve + * @param qt The query type + * @param cache Modified by the constructor if the result was cached + */ + UserResolver(InspIRCd* Instance, userrec* user, std::string to_resolve, QueryType qt, bool &cache); + + /** Called on successful lookup + * @param result Result string + * @param ttl Time to live for result + * @param cached True if the result was found in the cache + */ + void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached); + + /** Called on failed lookup + * @param e Error code + * @param errormessage Error message string + */ + void OnError(ResolverError e, const std::string &errormessage); +}; + + +/** Holds information relevent to <connect allow> and <connect deny> tags in the config file. + */ +class CoreExport ConnectClass : public classbase +{ + private: + /** Type of line, either CC_ALLOW or CC_DENY + */ + char type; + /** Max time to register the connection in seconds + */ + unsigned int registration_timeout; + /** Number of lines in buffer before excess flood is triggered + */ + unsigned int flood; + /** Host mask for this line + */ + std::string host; + /** Number of seconds between pings for this line + */ + unsigned int pingtime; + /** (Optional) Password for this line + */ + std::string pass; + + /** Threshold value for flood disconnect + */ + unsigned int threshold; + + /** Maximum size of sendq for users in this class (bytes) + */ + unsigned long sendqmax; + + /** Maximum size of recvq for users in this class (bytes) + */ + unsigned long recvqmax; + + /** Local max when connecting by this connection class + */ + unsigned long maxlocal; + + /** Global max when connecting by this connection class + */ + unsigned long maxglobal; + /** Port number this connect class applies to + */ + int port; + +public: + + /** Create a new connect class with no settings. + */ + ConnectClass() : type(CC_DENY), registration_timeout(0), flood(0), host(""), pingtime(0), pass(""), + threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0) { } + + /** Create a new connect class to ALLOW connections. + * @param timeout The registration timeout + * @param fld The flood value + * @param hst The IP mask to allow + * @param ping The ping frequency + * @param pas The password to be used + * @param thres The flooding threshold + * @param sendq The maximum sendq value + * @param recvq The maximum recvq value + * @param maxl The maximum local sessions + * @param maxg The maximum global sessions + */ + ConnectClass(unsigned int timeout, unsigned int fld, const std::string &hst, unsigned int ping, + const std::string &pas, unsigned int thres, unsigned long sendq, unsigned long recvq, + unsigned long maxl, unsigned long maxg, int p = 0) : + type(CC_ALLOW), registration_timeout(timeout), flood(fld), host(hst), pingtime(ping), pass(pas), + threshold(thres), sendqmax(sendq), recvqmax(recvq), maxlocal(maxl), maxglobal(maxg), port(p) { } + + /** Create a new connect class to DENY connections + * @param hst The IP mask to deny + */ + ConnectClass(const std::string &hst) : type(CC_DENY), registration_timeout(0), flood(0), host(hst), pingtime(0), + pass(""), threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0), port(0) { } + + /** Returns the type, CC_ALLOW or CC_DENY + */ + char GetType() + { + return (type == CC_ALLOW ? CC_ALLOW : CC_DENY); + } + + /** Returns the registration timeout + */ + unsigned int GetRegTimeout() + { + return (registration_timeout ? registration_timeout : 90); + } + + /** Returns the flood limit + */ + unsigned int GetFlood() + { + return (threshold ? flood : 999); + } + + /** Returns the allowed or denied IP mask + */ + const std::string& GetHost() + { + return host; + } + + int GetPort() + { + return port; + } + + /** Returns the ping frequency + */ + unsigned int GetPingTime() + { + return (pingtime ? pingtime : 120); + } + + /** Returns the password or an empty string + */ + const std::string& GetPass() + { + return pass; + } + + /** Returns the flood threshold value + */ + unsigned int GetThreshold() + { + return (threshold ? threshold : 1); + } + + /** Returns the maximum sendq value + */ + unsigned long GetSendqMax() + { + return (sendqmax ? sendqmax : 262114); + } + + /** Returns the maximum recvq value + */ + unsigned long GetRecvqMax() + { + return (recvqmax ? recvqmax : 4096); + } + + /** Returusn the maximum number of local sessions + */ + unsigned long GetMaxLocal() + { + return maxlocal; + } + + /** Returns the maximum number of global sessions + */ + unsigned long GetMaxGlobal() + { + return maxglobal; + } +}; + +/** Holds a complete list of all channels to which a user has been invited and has not yet joined. + */ +typedef std::vector<irc::string> InvitedList; + +/** Holds a complete list of all allow and deny tags from the configuration file (connection classes) + */ +typedef std::vector<ConnectClass> ClassVector; + +/** Typedef for the list of user-channel records for a user + */ +typedef std::map<chanrec*, char> UserChanList; + +/** Shorthand for an iterator into a UserChanList + */ +typedef UserChanList::iterator UCListIter; + +/* Required forward declaration + */ +class userrec; + +/** Visibility data for a user. + * If a user has a non-null instance of this class in their userrec, + * then it is used to determine if this user is visible to other users + * or not. + */ +class CoreExport VisData +{ + public: + /** Create a visdata + */ + VisData(); + /** Destroy a visdata + */ + virtual ~VisData(); + /** Is this user visible to some other user? + * @param user The other user to compare to + * @return true True if the user is visible to the other user, false if not + */ + virtual bool VisibleTo(userrec* user); +}; + +/** Holds all information about a user + * This class stores all information about a user connected to the irc server. Everything about a + * connection is stored here primarily, from the user's socket ID (file descriptor) through to the + * user's nickname and hostname. Use the FindNick method of the InspIRCd class to locate a specific user + * by nickname, or the FindDescriptor method of the InspIRCd class to find a specific user by their + * file descriptor value. + */ +class CoreExport userrec : public connection +{ + private: + /** Pointer to creator. + * This is required to make use of core functions + * from within the userrec class. + */ + InspIRCd* ServerInstance; + + /** A list of channels the user has a pending invite to. + * Upon INVITE channels are added, and upon JOIN, the + * channels are removed from this list. + */ + InvitedList invites; + + /** Number of channels this user is currently on + */ + unsigned int ChannelCount; + + /** Cached nick!ident@host value using the real hostname + */ + char* cached_fullhost; + + /** Cached nick!ident@ip value using the real IP address + */ + char* cached_hostip; + + /** Cached nick!ident@host value using the masked hostname + */ + char* cached_makehost; + + /** Cached nick!ident@realhost value using the real hostname + */ + char* cached_fullrealhost; + + /** When we erase the user (in the destructor), + * we call this method to subtract one from all + * mode characters this user is making use of. + */ + void DecrementModes(); + + /** Oper-only quit message for this user if non-null + */ + char* operquit; + + public: + /** Resolvers for looking up this users IP address + * This will occur if and when res_reverse completes. + * When this class completes its lookup, userrec::dns_done + * will be set from false to true. + */ + UserResolver* res_forward; + + /** Resolvers for looking up this users hostname + * This is instantiated by userrec::StartDNSLookup(), + * and on success, instantiates userrec::res_reverse. + */ + UserResolver* res_reverse; + + /** User visibility state, see definition of VisData. + */ + VisData* Visibility; + + /** Stored reverse lookup from res_forward + */ + std::string stored_host; + + /** Starts a DNS lookup of the user's IP. + * This will cause two UserResolver classes to be instantiated. + * When complete, these objects set userrec::dns_done to true. + */ + void StartDNSLookup(); + + /** The users nickname. + * An invalid nickname indicates an unregistered connection prior to the NICK command. + * Use InspIRCd::IsNick() to validate nicknames. + */ + char nick[NICKMAX]; + + /** The users ident reply. + * Two characters are added to the user-defined limit to compensate for the tilde etc. + */ + char ident[IDENTMAX+2]; + + /** The host displayed to non-opers (used for cloaking etc). + * This usually matches the value of userrec::host. + */ + char dhost[65]; + + /** The users full name (GECOS). + */ + char fullname[MAXGECOS+1]; + + /** The user's mode list. + * This is NOT a null terminated string! In the 1.1 version of InspIRCd + * this is an array of values in a similar way to channel modes. + * A value of 1 in field (modeletter-65) indicates that the mode is + * set, for example, to work out if mode +s is set, we check the field + * userrec::modes['s'-65] != 0. + * The following RFC characters o, w, s, i have constants defined via an + * enum, such as UM_SERVERNOTICE and UM_OPETATOR. + */ + char modes[64]; + + /** What snomasks are set on this user. + * This functions the same as the above modes. + */ + char snomasks[64]; + + /** Channels this user is on, and the permissions they have there + */ + UserChanList chans; + + /** The server the user is connected to. + */ + const char* server; + + /** The user's away message. + * If this string is empty, the user is not marked as away. + */ + char awaymsg[MAXAWAY+1]; + + /** Number of lines the user can place into the buffer + * (up to the global NetBufferSize bytes) before they + * are disconnected for excess flood + */ + int flood; + + /** Timestamp of current time + connection class timeout. + * This user must send USER/NICK before this timestamp is + * reached or they will be disconnected. + */ + time_t timeout; + + /** The oper type they logged in as, if they are an oper. + * This is used to check permissions in operclasses, so that + * we can say 'yay' or 'nay' to any commands they issue. + * The value of this is the value of a valid 'type name=' tag. + */ + char oper[NICKMAX]; + + /** True when DNS lookups are completed. + * The UserResolver classes res_forward and res_reverse will + * set this value once they complete. + */ + bool dns_done; + + /** Number of seconds between PINGs for this user (set from <connect:allow> tag + */ + unsigned int pingmax; + + /** Password specified by the user when they registered. + * This is stored even if the <connect> block doesnt need a password, so that + * modules may check it. + */ + char password[64]; + + /** User's receive queue. + * Lines from the IRCd awaiting processing are stored here. + * Upgraded april 2005, old system a bit hairy. + */ + std::string recvq; + + /** User's send queue. + * Lines waiting to be sent are stored here until their buffer is flushed. + */ + std::string sendq; + + /** Flood counters - lines received + */ + int lines_in; + + /** Flood counters - time lines_in is due to be reset + */ + time_t reset_due; + + /** Flood counters - Highest value lines_in may reach before the user gets disconnected + */ + long threshold; + + /** If this is set to true, then all read operations for the user + * are dropped into the bit-bucket. + * This is used by the global CullList, but please note that setting this value + * alone will NOT cause the user to quit. This means it can be used seperately, + * for example by shun modules etc. + */ + bool muted; + + /** IPV4 or IPV6 ip address. Use SetSockAddr to set this and GetProtocolFamily/ + * GetIPString/GetPort to obtain its values. + */ + sockaddr* ip; + + /** Initialize the clients sockaddr + * @param protocol_family The protocol family of the IP address, AF_INET or AF_INET6 + * @param ip A human-readable IP address for this user matching the protcol_family + * @param port The port number of this user or zero for a remote user + */ + void SetSockAddr(int protocol_family, const char* ip, int port); + + /** Get port number from sockaddr + * @return The port number of this user. + */ + int GetPort(); + + /** Get protocol family from sockaddr + * @return The protocol family of this user, either AF_INET or AF_INET6 + */ + int GetProtocolFamily(); + + /** Get IP string from sockaddr, using static internal buffer + * @return The IP string + */ + const char* GetIPString(); + + /** Get IP string from sockaddr, using caller-specified buffer + * @param buf A buffer to use + * @return The IP string + */ + const char* GetIPString(char* buf); + + /* Write error string + */ + std::string WriteError; + + /** Maximum size this user's sendq can become. + * Copied from the connect class on connect. + */ + long sendqmax; + + /** Maximum size this user's recvq can become. + * Copied from the connect class on connect. + */ + long recvqmax; + + /** This is true if the user matched an exception when they connected to the ircd. + * It isnt valid after this point, and you should not attempt to do anything with it + * after this point, because the eline might be removed at a later time, and/or no + * longer be applicable to this user. It is only used to save doing the eline lookup + * twice (instead we do it once and set this value). + */ + bool exempt; + + /** Default constructor + * @throw Nothing at present + */ + userrec(InspIRCd* Instance); + + /** Returns the full displayed host of the user + * This member function returns the hostname of the user as seen by other users + * on the server, in nick!ident&at;host form. + * @return The full masked host of the user + */ + virtual char* GetFullHost(); + + /** Returns the full real host of the user + * This member function returns the hostname of the user as seen by other users + * on the server, in nick!ident&at;host form. If any form of hostname cloaking is in operation, + * e.g. through a module, then this method will ignore it and return the true hostname. + * @return The full real host of the user + */ + virtual char* GetFullRealHost(); + + /** This clears any cached results that are used for GetFullRealHost() etc. + * The results of these calls are cached as generating them can be generally expensive. + */ + void InvalidateCache(); + + /** Create a displayable mode string for this users snomasks + * @return The notice mask character sequence + */ + const char* FormatNoticeMasks(); + + /** Process a snomask modifier string, e.g. +abc-de + * @param sm A sequence of notice mask characters + * @return The cleaned mode sequence which can be output, + * e.g. in the above example if masks c and e are not + * valid, this function will return +ab-d + */ + std::string ProcessNoticeMasks(const char *sm); + + /** Returns true if a notice mask is set + * @param sm A notice mask character to check + * @return True if the notice mask is set + */ + bool IsNoticeMaskSet(unsigned char sm); + + /** Changed a specific notice mask value + * @param sm The server notice mask to change + * @param value An on/off value for this mask + */ + void SetNoticeMask(unsigned char sm, bool value); + + /** Create a displayable mode string for this users umodes + * @param The mode string + */ + const char* FormatModes(); + + /** Returns true if a specific mode is set + * @param m The user mode + * @return True if the mode is set + */ + bool IsModeSet(unsigned char m); + + /** Set a specific usermode to on or off + * @param m The user mode + * @param value On or off setting of the mode + */ + void SetMode(unsigned char m, bool value); + + /** Returns true if a user is invited to a channel. + * @param channel A channel name to look up + * @return True if the user is invited to the given channel + */ + virtual bool IsInvited(const irc::string &channel); + + /** Adds a channel to a users invite list (invites them to a channel) + * @param channel A channel name to add + */ + virtual void InviteTo(const irc::string &channel); + + /** Removes a channel from a users invite list. + * This member function is called on successfully joining an invite only channel + * to which the user has previously been invited, to clear the invitation. + * @param channel The channel to remove the invite to + */ + virtual void RemoveInvite(const irc::string &channel); + + /** Returns true or false for if a user can execute a privilaged oper command. + * This is done by looking up their oper type from userrec::oper, then referencing + * this to their oper classes and checking the commands they can execute. + * @param command A command (should be all CAPS) + * @return True if this user can execute the command + */ + bool HasPermission(const std::string &command); + + /** Calls read() to read some data for this user using their fd. + * @param buffer The buffer to read into + * @param size The size of data to read + * @return The number of bytes read, or -1 if an error occured. + */ + int ReadData(void* buffer, size_t size); + + /** This method adds data to the read buffer of the user. + * The buffer can grow to any size within limits of the available memory, + * managed by the size of a std::string, however if any individual line in + * the buffer grows over 600 bytes in length (which is 88 chars over the + * RFC-specified limit per line) then the method will return false and the + * text will not be inserted. + * @param a The string to add to the users read buffer + * @return True if the string was successfully added to the read buffer + */ + bool AddBuffer(std::string a); + + /** This method returns true if the buffer contains at least one carriage return + * character (e.g. one complete line may be read) + * @return True if there is at least one complete line in the users buffer + */ + bool BufferIsReady(); + + /** This function clears the entire buffer by setting it to an empty string. + */ + void ClearBuffer(); + + /** This method returns the first available string at the tail end of the buffer + * and advances the tail end of the buffer past the string. This means it is + * a one way operation in a similar way to strtok(), and multiple calls return + * multiple lines if they are available. The results of this function if there + * are no lines to be read are unknown, always use BufferIsReady() to check if + * it is ok to read the buffer before calling GetBuffer(). + * @return The string at the tail end of this users buffer + */ + std::string GetBuffer(); + + /** Sets the write error for a connection. This is done because the actual disconnect + * of a client may occur at an inopportune time such as half way through /LIST output. + * The WriteErrors of clients are checked at a more ideal time (in the mainloop) and + * errored clients purged. + * @param error The error string to set. + */ + void SetWriteError(const std::string &error); + + /** Returns the write error which last occured on this connection or an empty string + * if none occured. + * @return The error string which has occured for this user + */ + const char* GetWriteError(); + + /** Adds to the user's write buffer. + * You may add any amount of text up to this users sendq value, if you exceed the + * sendq value, SetWriteError() will be called to set the users error string to + * "SendQ exceeded", and further buffer adds will be dropped. + * @param data The data to add to the write buffer + */ + void AddWriteBuf(const std::string &data); + + /** Flushes as much of the user's buffer to the file descriptor as possible. + * This function may not always flush the entire buffer, rather instead as much of it + * as it possibly can. If the send() call fails to send the entire buffer, the buffer + * position is advanced forwards and the rest of the data sent at the next call to + * this method. + */ + void FlushWriteBuf(); + + /** Returns the list of channels this user has been invited to but has not yet joined. + * @return A list of channels the user is invited to + */ + InvitedList* GetInviteList(); + + /** Creates a wildcard host. + * Takes a buffer to use and fills the given buffer with the host in the format *!*@hostname + * @return The wildcarded hostname in *!*@host form + */ + char* MakeWildHost(); + + /** Creates a usermask with real host. + * Takes a buffer to use and fills the given buffer with the hostmask in the format user@host + * @return the usermask in the format user@host + */ + char* MakeHost(); + + /** Creates a usermask with real ip. + * Takes a buffer to use and fills the given buffer with the ipmask in the format user@ip + * @return the usermask in the format user@ip + */ + char* MakeHostIP(); + + /** Shuts down and closes the user's socket + * This will not cause the user to be deleted. Use InspIRCd::QuitUser for this, + * which will call CloseSocket() for you. + */ + void CloseSocket(); + + /** Disconnect a user gracefully + * @param user The user to remove + * @param r The quit reason to show to normal users + * @param oreason The quit reason to show to opers + * @return Although this function has no return type, on exit the user provided will no longer exist. + */ + static void QuitUser(InspIRCd* Instance, userrec *user, const std::string &r, const char* oreason = ""); + + /** Add the user to WHOWAS system + */ + void AddToWhoWas(); + + /** Oper up the user using the given opertype. + * This will also give the +o usermode. + * @param opertype The oper type to oper as + */ + void Oper(const std::string &opertype); + + /** Call this method to find the matching <connect> for a user, and to check them against it. + */ + void CheckClass(); + + /** Use this method to fully connect a user. + * This will send the message of the day, check G/K/E lines, etc. + */ + void FullConnect(); + + /** Change this users hash key to a new string. + * You should not call this function directly. It is used by the core + * to update the users hash entry on a nickchange. + * @param New new user_hash key + * @return Pointer to userrec in hash (usually 'this') + */ + userrec* UpdateNickHash(const char* New); + + /** Force a nickname change. + * If the nickname change fails (for example, because the nick in question + * already exists) this function will return false, and you must then either + * output an error message, or quit the user for nickname collision. + * @param newnick The nickname to change to + * @return True if the nickchange was successful. + */ + bool ForceNickChange(const char* newnick); + + /** Add a client to the system. + * This will create a new userrec, insert it into the user_hash, + * initialize it as not yet registered, and add it to the socket engine. + * @param Instance a pointer to the server instance + * @param socket The socket id (file descriptor) this user is on + * @param port The port number this user connected on + * @param iscached This variable is reserved for future use + * @param ip The IP address of the user + * @return This function has no return value, but a call to AddClient may remove the user. + */ + static void AddClient(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip); + + /** Oper down. + * This will clear the +o usermode and unset the user's oper type + */ + void UnOper(); + + /** Return the number of global clones of this user + * @return The global clone count of this user + */ + unsigned long GlobalCloneCount(); + + /** Return the number of local clones of this user + * @return The local clone count of this user + */ + unsigned long LocalCloneCount(); + + /** Remove all clone counts from the user, you should + * use this if you change the user's IP address in + * userrec::ip after they have registered. + */ + void RemoveCloneCounts(); + + /** Write text to this user, appending CR/LF. + * @param text A std::string to send to the user + */ + void Write(std::string text); + + /** Write text to this user, appending CR/LF. + * @param text The format string for text to send to the user + * @param ... POD-type format arguments + */ + void Write(const char *text, ...); + + /** Write text to this user, appending CR/LF and prepending :server.name + * @param text A std::string to send to the user + */ + void WriteServ(const std::string& text); + + /** Write text to this user, appending CR/LF and prepending :server.name + * @param text The format string for text to send to the user + * @param ... POD-type format arguments + */ + void WriteServ(const char* text, ...); + + /** Write text to this user, appending CR/LF and prepending :nick!user@host of the user provided in the first parameter. + * @param user The user to prepend the :nick!user@host of + * @param text A std::string to send to the user + */ + void WriteFrom(userrec *user, const std::string &text); + + /** Write text to this user, appending CR/LF and prepending :nick!user@host of the user provided in the first parameter. + * @param user The user to prepend the :nick!user@host of + * @param text The format string for text to send to the user + * @param ... POD-type format arguments + */ + void WriteFrom(userrec *user, const char* text, ...); + + /** Write text to the user provided in the first parameter, appending CR/LF, and prepending THIS user's :nick!user@host. + * @param dest The user to route the message to + * @param text A std::string to send to the user + */ + void WriteTo(userrec *dest, const std::string &data); + + /** Write text to the user provided in the first parameter, appending CR/LF, and prepending THIS user's :nick!user@host. + * @param dest The user to route the message to + * @param text The format string for text to send to the user + * @param ... POD-type format arguments + */ + void WriteTo(userrec *dest, const char *data, ...); + + /** Write to all users that can see this user (including this user in the list), appending CR/LF + * @param text A std::string to send to the users + */ + void WriteCommon(const std::string &text); + + /** Write to all users that can see this user (including this user in the list), appending CR/LF + * @param text The format string for text to send to the users + * @param ... POD-type format arguments + */ + void WriteCommon(const char* text, ...); + + /** Write to all users that can see this user (not including this user in the list), appending CR/LF + * @param text The format string for text to send to the users + * @param ... POD-type format arguments + */ + void WriteCommonExcept(const char* text, ...); + + /** Write to all users that can see this user (not including this user in the list), appending CR/LF + * @param text A std::string to send to the users + */ + void WriteCommonExcept(const std::string &text); + + /** Write a quit message to all common users, as in userrec::WriteCommonExcept but with a specific + * quit message for opers only. + * @param normal_text Normal user quit message + * @param oper_text Oper only quit message + */ + void WriteCommonQuit(const std::string &normal_text, const std::string &oper_text); + + /** Write a WALLOPS message from this user to all local opers. + * If this user is not opered, the function will return without doing anything. + * @param text The format string to send in the WALLOPS message + * @param ... Format arguments + */ + void WriteWallOps(const char* text, ...); + + /** Write a WALLOPS message from this user to all local opers. + * If this user is not opered, the function will return without doing anything. + * @param text The text to send in the WALLOPS message + */ + void WriteWallOps(const std::string &text); + + /** Return true if the user shares at least one channel with another user + * @param other The other user to compare the channel list against + * @return True if the given user shares at least one channel with this user + */ + bool SharesChannelWith(userrec *other); + + /** Change the displayed host of a user. + * ALWAYS use this function, rather than writing userrec::dhost directly, + * as this triggers module events allowing the change to be syncronized to + * remote servers. This will also emulate a QUIT and rejoin (where configured) + * before setting their host field. + * @param host The new hostname to set + * @return True if the change succeeded, false if it didn't + */ + bool ChangeDisplayedHost(const char* host); + + /** Change the ident (username) of a user. + * ALWAYS use this function, rather than writing userrec::ident directly, + * as this correctly causes the user to seem to quit (where configured) + * before setting their ident field. + * @param host The new ident to set + * @return True if the change succeeded, false if it didn't + */ + bool ChangeIdent(const char* newident); + + /** Change a users realname field. + * ALWAYS use this function, rather than writing userrec::fullname directly, + * as this triggers module events allowing the change to be syncronized to + * remote servers. + * @param gecos The user's new realname + * @return True if the change succeeded, false if otherwise + */ + bool ChangeName(const char* gecos); + + /** Send a command to all local users from this user + * The command given must be able to send text with the + * first parameter as a servermask (e.g. $*), so basically + * you should use PRIVMSG or NOTICE. + * @param command the command to send + * @param text The text format string to send + * @param ... Format arguments + */ + void SendAll(const char* command, char* text, ...); + + /** Compile a channel list for this user, and send it to the user 'source' + * Used internally by WHOIS + * @param The user to send the channel list to if it is not too long + * @return This user's channel list + */ + std::string ChannelList(userrec* source); + + /** Split the channel list in cl which came from dest, and spool it to this user + * Used internally by WHOIS + * @param dest The user the original channel list came from + * @param cl The channel list as a string obtained from userrec::ChannelList() + */ + void SplitChanList(userrec* dest, const std::string &cl); + + /** Remove this user from all channels they are on, and delete any that are now empty. + * This is used by QUIT, and will not send part messages! + */ + void PurgeEmptyChannels(); + + /** Get the connect class which matches this user's host or IP address + * @return A reference to this user's connect class + */ + ConnectClass* GetClass(); + + /** Show the message of the day to this user + */ + void ShowMOTD(); + + /** Show the server RULES file to this user + */ + void ShowRULES(); + + /** Set oper-specific quit message shown to opers only when the user quits + * (overrides any sent by QuitUser) + */ + void SetOperQuit(const std::string &oquit); + + /** Get oper-specific quit message shown only to opers when the user quits. + * (overrides any sent by QuitUser) + */ + const char* GetOperQuit(); + + /** Handle socket event. + * From EventHandler class. + * @param et Event type + * @param errornum Error number for EVENT_ERROR events + */ + void HandleEvent(EventType et, int errornum = 0); + + /** Default destructor + */ + virtual ~userrec(); +}; + +/* Configuration callbacks */ +class ServerConfig; + +#endif + diff --git a/include/wildcard.h b/include/wildcard.h index c58d4bfc1..259d86184 100644 --- a/include/wildcard.h +++ b/include/wildcard.h @@ -1 +1,45 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#include "inspircd_config.h"
/** Match a string against a mask.
* @param str The string to check
* @param mask the mask to check against
* @return true if the strings match
*/
CoreExport bool match(const char *str, const char *mask);
/** Match a string against a mask, and define wether or not to use CIDR rules
* @param str The string to check
* @param mask the mask to check against
* @param use_cidr_match True if CIDR matching rules should be applied first
* @return true if the strings match
*/
CoreExport bool match(const char *str, const char *mask, bool use_cidr_match);
/** Match a string against a mask, defining wether case sensitivity applies.
* @param str The string to check
* @param mask the mask to check against
* @param case_sensitive True if the match is case sensitive
* @return True if the strings match
*/
CoreExport bool match(bool case_sensitive, const char *str, const char *mask);
/** Match a string against a mask, defining wether case sensitivity applies,
* and defining wether or not to use CIDR rules first.
* @param case_sensitive True if the match is case sensitive
* @param str The string to check
* @param mask the mask to check against
* @param use_cidr_match True if CIDR matching rules should be applied first
* @return true if the strings match
*/
CoreExport bool match(bool case_sensitive, const char *str, const char *mask, bool use_cidr_match);
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#include "inspircd_config.h" + +/** Match a string against a mask. + * @param str The string to check + * @param mask the mask to check against + * @return true if the strings match + */ +CoreExport bool match(const char *str, const char *mask); +/** Match a string against a mask, and define wether or not to use CIDR rules + * @param str The string to check + * @param mask the mask to check against + * @param use_cidr_match True if CIDR matching rules should be applied first + * @return true if the strings match + */ +CoreExport bool match(const char *str, const char *mask, bool use_cidr_match); +/** Match a string against a mask, defining wether case sensitivity applies. + * @param str The string to check + * @param mask the mask to check against + * @param case_sensitive True if the match is case sensitive + * @return True if the strings match + */ +CoreExport bool match(bool case_sensitive, const char *str, const char *mask); +/** Match a string against a mask, defining wether case sensitivity applies, + * and defining wether or not to use CIDR rules first. + * @param case_sensitive True if the match is case sensitive + * @param str The string to check + * @param mask the mask to check against + * @param use_cidr_match True if CIDR matching rules should be applied first + * @return true if the strings match + */ +CoreExport bool match(bool case_sensitive, const char *str, const char *mask, bool use_cidr_match); + diff --git a/include/xline.h b/include/xline.h index 5695c3788..bb59a9735 100644 --- a/include/xline.h +++ b/include/xline.h @@ -1 +1,530 @@ -/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* 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.
*
* ---------------------------------------------------
*/
#ifndef __XLINE_H
#define __XLINE_H
// include the common header files
#include <string>
#include <deque>
#include <vector>
#include "users.h"
#include "channels.h"
const int APPLY_GLINES = 1;
const int APPLY_KLINES = 2;
const int APPLY_QLINES = 4;
const int APPLY_ZLINES = 8;
const int APPLY_PERM_ONLY = 16;
const int APPLY_ALL = APPLY_GLINES | APPLY_KLINES | APPLY_QLINES | APPLY_ZLINES;
/** XLine is the base class for ban lines such as G lines and K lines.
*/
class CoreExport XLine : public classbase
{
public:
/** Create an XLine.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
* @param re The reason of the xline
*/
XLine(time_t s_time, long d, const char* src, const char* re)
: set_time(s_time), duration(d)
{
source = strdup(src);
reason = strdup(re);
expiry = set_time + duration;
}
/** Destructor
*/
virtual ~XLine()
{
free(reason);
free(source);
}
/** The time the line was added.
*/
time_t set_time;
/** The duration of the ban, or 0 if permenant
*/
long duration;
/** Source of the ban. This can be a servername or an oper nickname
*/
char* source;
/** Reason for the ban
*/
char* reason;
/** Expiry time
*/
time_t expiry;
};
/** KLine class
*/
class CoreExport KLine : public XLine
{
public:
/** Create a K-Line.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
* @param re The reason of the xline
* @param ident Ident to match
* @param host Host to match
*/
KLine(time_t s_time, long d, const char* src, const char* re, const char* ident, const char* host) : XLine(s_time, d, src, re)
{
identmask = strdup(ident);
hostmask = strdup(host);
}
/** Destructor
*/
~KLine()
{
free(identmask);
free(hostmask);
}
/** Ident mask
*/
char* identmask;
/** Host mask
*/
char* hostmask;
};
/** GLine class
*/
class CoreExport GLine : public XLine
{
public:
/** Create a G-Line.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
* @param re The reason of the xline
* @param ident Ident to match
* @param host Host to match
*/
GLine(time_t s_time, long d, const char* src, const char* re, const char* ident, const char* host) : XLine(s_time, d, src, re)
{
identmask = strdup(ident);
hostmask = strdup(host);
}
/** Destructor
*/
~GLine()
{
free(identmask);
free(hostmask);
}
/** Ident mask
*/
char* identmask;
/** Host mask
*/
char* hostmask;
};
/** ELine class
*/
class CoreExport ELine : public XLine
{
public:
/** Create an E-Line.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
* @param re The reason of the xline
* @param ident Ident to match
* @param host Host to match
*/
ELine(time_t s_time, long d, const char* src, const char* re, const char* ident, const char* host) : XLine(s_time, d, src, re)
{
identmask = strdup(ident);
hostmask = strdup(host);
}
~ELine()
{
free(identmask);
free(hostmask);
}
/** Ident mask
*/
char* identmask;
/** Host mask
*/
char* hostmask;
};
/** ZLine class
*/
class CoreExport ZLine : public XLine
{
public:
/** Create a Z-Line.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
* @param re The reason of the xline
* @param ip IP to match
*/
ZLine(time_t s_time, long d, const char* src, const char* re, const char* ip) : XLine(s_time, d, src, re)
{
ipaddr = strdup(ip);
}
/** Destructor
*/
~ZLine()
{
free(ipaddr);
}
/** IP mask
*/
char* ipaddr;
};
/** QLine class
*/
class CoreExport QLine : public XLine
{
public:
/** Create a G-Line.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
* @param re The reason of the xline
* @param nickname Nickname to match
*/
QLine(time_t s_time, long d, const char* src, const char* re, const char* nickname) : XLine(s_time, d, src, re)
{
nick = strdup(nickname);
}
/** Destructor
*/
~QLine()
{
free(nick);
}
/** Nickname mask
*/
char* nick;
};
/* Required forward declarations
*/
class ServerConfig;
class InspIRCd;
/** Initialize x line
*/
bool InitXLine(ServerConfig* conf, const char* tag);
/** Done adding zlines from the config
*/
bool DoneZLine(ServerConfig* conf, const char* tag);
/** Done adding qlines from the config
*/
bool DoneQLine(ServerConfig* conf, const char* tag);
/** Done adding klines from the config
*/
bool DoneKLine(ServerConfig* conf, const char* tag);
/** Done adding elines from the config
*/
bool DoneELine(ServerConfig* conf, const char* tag);
/** Add a config-defined zline
*/
bool DoZLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
/** Add a config-defined qline
*/
bool DoQLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
/** Add a config-defined kline
*/
bool DoKLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
/** Add a config-defined eline
*/
bool DoELine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
/** Contains an ident and host split into two strings
*/
typedef std::pair<std::string, std::string> IdentHostPair;
/** XLineManager is a class used to manage glines, klines, elines, zlines and qlines.
*/
class CoreExport XLineManager
{
protected:
/** The owner/creator of this class
*/
InspIRCd* ServerInstance;
/** This functor is used by the std::sort() function to keep glines in order
*/
static bool GSortComparison ( const GLine* one, const GLine* two );
/** This functor is used by the std::sort() function to keep elines in order
*/
static bool ESortComparison ( const ELine* one, const ELine* two );
/** This functor is used by the std::sort() function to keep zlines in order
*/
static bool ZSortComparison ( const ZLine* one, const ZLine* two );
/** This functor is used by the std::sort() function to keep klines in order
*/
static bool KSortComparison ( const KLine* one, const KLine* two );
/** This functor is used by the std::sort() function to keep qlines in order
*/
static bool QSortComparison ( const QLine* one, const QLine* two );
public:
/* Lists for temporary lines with an expiry time */
/** Temporary KLines */
std::vector<KLine*> klines;
/** Temporary Glines */
std::vector<GLine*> glines;
/** Temporary Zlines */
std::vector<ZLine*> zlines;
/** Temporary QLines */
std::vector<QLine*> qlines;
/** Temporary ELines */
std::vector<ELine*> elines;
/* Seperate lists for perm XLines that isnt checked by expiry functions */
/** Permenant KLines */
std::vector<KLine*> pklines;
/** Permenant GLines */
std::vector<GLine*> pglines;
/** Permenant ZLines */
std::vector<ZLine*> pzlines;
/** Permenant QLines */
std::vector<QLine*> pqlines;
/** Permenant ELines */
std::vector<ELine*> pelines;
/** Constructor
* @param Instance A pointer to the creator object
*/
XLineManager(InspIRCd* Instance);
/** Split an ident and host into two seperate strings.
* This allows for faster matching.
*/
IdentHostPair IdentSplit(const std::string &ident_and_host);
/** Add a new GLine
* @param duration The duration of the line
* @param source The source of the line
* @param reason The reason for the line
* @param hostmask The hostmask
* @return True if the line was added successfully
*/
bool add_gline(long duration, const char* source, const char* reason, const char* hostmask);
/** Add a new QLine
* @param duration The duration of the line
* @param source The source of the line
* @param reason The reason for the line
* @param nickname The nickmask
* @return True if the line was added successfully
*/
bool add_qline(long duration, const char* source, const char* reason, const char* nickname);
/** Add a new ZLine
* @param duration The duration of the line
* @param source The source of the line
* @param reason The reason for the line
* @param ipaddr The IP mask
* @return True if the line was added successfully
*/
bool add_zline(long duration, const char* source, const char* reason, const char* ipaddr);
/** Add a new KLine
* @param duration The duration of the line
* @param source The source of the line
* @param reason The reason for the line
* @param hostmask The hostmask
* @return True if the line was added successfully
*/
bool add_kline(long duration, const char* source, const char* reason, const char* hostmask);
/** Add a new ELine
* @param duration The duration of the line
* @param source The source of the line
* @param reason The reason for the line
* @param hostmask The hostmask
* @return True if the line was added successfully
*/
bool add_eline(long duration, const char* source, const char* reason, const char* hostmask);
/** Delete a GLine
* @param hostmask The host to remove
* @param simulate If this is true, don't actually remove the line, just return
* @return True if the line was deleted successfully
*/
bool del_gline(const char* hostmask, bool simulate = false);
/** Delete a QLine
* @param nickname The nick to remove
* @param simulate If this is true, don't actually remove the line, just return
* @return True if the line was deleted successfully
*/
bool del_qline(const char* nickname, bool simulate = false);
/** Delete a ZLine
* @param ipaddr The IP to remove
* @param simulate If this is true, don't actually remove the line, just return
* @return True if the line was deleted successfully
*/
bool del_zline(const char* ipaddr, bool simulate = false);
/** Delete a KLine
* @param hostmask The host to remove
* @param simulate If this is true, don't actually remove the line, just return
* @return True if the line was deleted successfully
*/
bool del_kline(const char* hostmask, bool simulate = false);
/** Delete a ELine
* @param hostmask The host to remove
* @param simulate If this is true, don't actually remove the line, just return
* @return True if the line was deleted successfully
*/
bool del_eline(const char* hostmask, bool simulate = false);
/** Check if a nickname matches a QLine
* @return nick The nick to check against
* @return The reason for the line if there is a match, or NULL if there is no match
*/
QLine* matches_qline(const char* nick, bool permonly = false);
/** Check if a hostname matches a GLine
* @param user The user to check against
* @return The reason for the line if there is a match, or NULL if there is no match
*/
GLine* matches_gline(userrec* user, bool permonly = false);
/** Check if a IP matches a ZLine
* @param ipaddr The IP to check against
* @return The reason for the line if there is a match, or NULL if there is no match
*/
ZLine* matches_zline(const char* ipaddr, bool permonly = false);
/** Check if a hostname matches a KLine
* @param user The user to check against
* @return The reason for the line if there is a match, or NULL if there is no match
*/
KLine* matches_kline(userrec* user, bool permonly = false);
/** Check if a hostname matches a ELine
* @param user The user to check against
* @return The reason for the line if there is a match, or NULL if there is no match
*/
ELine* matches_exception(userrec* user, bool permonly = false);
/** Expire any pending non-permenant lines
*/
void expire_lines();
/** Apply any new lines
* @param What The types of lines to apply, from the set
* APPLY_GLINES | APPLY_KLINES | APPLY_QLINES | APPLY_ZLINES | APPLY_ALL
* | APPLY_LOCAL_ONLY
*/
void apply_lines(const int What);
/** Handle /STATS K
* @param user The username making the query
* @param results The string_list to receive the results
*/
void stats_k(userrec* user, string_list &results);
/** Handle /STATS G
* @param user The username making the query
* @param results The string_list to receive the results
*/
void stats_g(userrec* user, string_list &results);
/** Handle /STATS Q
* @param user The username making the query
* @param results The string_list to receive the results
*/
void stats_q(userrec* user, string_list &results);
/** Handle /STATS Z
* @param user The username making the query
* @param results The string_list to receive the results
*/
void stats_z(userrec* user, string_list &results);
/** Handle /STATS E
* @param user The username making the query
* @param results The string_list to receive the results
*/
void stats_e(userrec* user, string_list &results);
/** Change creation time of a GLine
* @param host The hostname to change
* @param create_Time The new creation time
*/
void gline_set_creation_time(const char* host, time_t create_time);
/** Change creation time of a QLine
* @param nick The nickmask to change
* @param create_Time The new creation time
*/
void qline_set_creation_time(const char* nick, time_t create_time);
/** Change creation time of a ZLine
* @param ip The ipmask to change
* @param create_Time The new creation time
*/
void zline_set_creation_time(const char* ip, time_t create_time);
/** Change creation time of a ELine
* @param host The hostname to change
* @param create_Time The new creation time
*/
void eline_set_creation_time(const char* host, time_t create_time);
};
#endif
\ No newline at end of file +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * 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. + * + * --------------------------------------------------- + */ + +#ifndef __XLINE_H +#define __XLINE_H + +// include the common header files + +#include <string> +#include <deque> +#include <vector> +#include "users.h" +#include "channels.h" + +const int APPLY_GLINES = 1; +const int APPLY_KLINES = 2; +const int APPLY_QLINES = 4; +const int APPLY_ZLINES = 8; +const int APPLY_PERM_ONLY = 16; +const int APPLY_ALL = APPLY_GLINES | APPLY_KLINES | APPLY_QLINES | APPLY_ZLINES; + +/** XLine is the base class for ban lines such as G lines and K lines. + */ +class CoreExport XLine : public classbase +{ + public: + + /** Create an XLine. + * @param s_time The set time + * @param d The duration of the xline + * @param src The sender of the xline + * @param re The reason of the xline + */ + XLine(time_t s_time, long d, const char* src, const char* re) + : set_time(s_time), duration(d) + { + source = strdup(src); + reason = strdup(re); + expiry = set_time + duration; + } + + /** Destructor + */ + virtual ~XLine() + { + free(reason); + free(source); + } + /** The time the line was added. + */ + time_t set_time; + + /** The duration of the ban, or 0 if permenant + */ + long duration; + + /** Source of the ban. This can be a servername or an oper nickname + */ + char* source; + + /** Reason for the ban + */ + char* reason; + + /** Expiry time + */ + time_t expiry; +}; + +/** KLine class + */ +class CoreExport KLine : public XLine +{ + public: + /** Create a K-Line. + * @param s_time The set time + * @param d The duration of the xline + * @param src The sender of the xline + * @param re The reason of the xline + * @param ident Ident to match + * @param host Host to match + */ + KLine(time_t s_time, long d, const char* src, const char* re, const char* ident, const char* host) : XLine(s_time, d, src, re) + { + identmask = strdup(ident); + hostmask = strdup(host); + } + + /** Destructor + */ + ~KLine() + { + free(identmask); + free(hostmask); + } + + /** Ident mask + */ + char* identmask; + /** Host mask + */ + char* hostmask; +}; + +/** GLine class + */ +class CoreExport GLine : public XLine +{ + public: + /** Create a G-Line. + * @param s_time The set time + * @param d The duration of the xline + * @param src The sender of the xline + * @param re The reason of the xline + * @param ident Ident to match + * @param host Host to match + */ + GLine(time_t s_time, long d, const char* src, const char* re, const char* ident, const char* host) : XLine(s_time, d, src, re) + { + identmask = strdup(ident); + hostmask = strdup(host); + } + + /** Destructor + */ + ~GLine() + { + free(identmask); + free(hostmask); + } + + /** Ident mask + */ + char* identmask; + /** Host mask + */ + char* hostmask; +}; + +/** ELine class + */ +class CoreExport ELine : public XLine +{ + public: + /** Create an E-Line. + * @param s_time The set time + * @param d The duration of the xline + * @param src The sender of the xline + * @param re The reason of the xline + * @param ident Ident to match + * @param host Host to match + */ + ELine(time_t s_time, long d, const char* src, const char* re, const char* ident, const char* host) : XLine(s_time, d, src, re) + { + identmask = strdup(ident); + hostmask = strdup(host); + } + + ~ELine() + { + free(identmask); + free(hostmask); + } + + /** Ident mask + */ + char* identmask; + /** Host mask + */ + char* hostmask; +}; + +/** ZLine class + */ +class CoreExport ZLine : public XLine +{ + public: + /** Create a Z-Line. + * @param s_time The set time + * @param d The duration of the xline + * @param src The sender of the xline + * @param re The reason of the xline + * @param ip IP to match + */ + ZLine(time_t s_time, long d, const char* src, const char* re, const char* ip) : XLine(s_time, d, src, re) + { + ipaddr = strdup(ip); + } + + /** Destructor + */ + ~ZLine() + { + free(ipaddr); + } + + /** IP mask + */ + char* ipaddr; +}; + +/** QLine class + */ +class CoreExport QLine : public XLine +{ + public: + /** Create a G-Line. + * @param s_time The set time + * @param d The duration of the xline + * @param src The sender of the xline + * @param re The reason of the xline + * @param nickname Nickname to match + */ + QLine(time_t s_time, long d, const char* src, const char* re, const char* nickname) : XLine(s_time, d, src, re) + { + nick = strdup(nickname); + } + + /** Destructor + */ + ~QLine() + { + free(nick); + } + + /** Nickname mask + */ + char* nick; +}; + +/* Required forward declarations + */ +class ServerConfig; +class InspIRCd; + +/** Initialize x line + */ +bool InitXLine(ServerConfig* conf, const char* tag); + +/** Done adding zlines from the config + */ +bool DoneZLine(ServerConfig* conf, const char* tag); +/** Done adding qlines from the config + */ +bool DoneQLine(ServerConfig* conf, const char* tag); +/** Done adding klines from the config + */ +bool DoneKLine(ServerConfig* conf, const char* tag); +/** Done adding elines from the config + */ +bool DoneELine(ServerConfig* conf, const char* tag); + +/** Add a config-defined zline + */ +bool DoZLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types); +/** Add a config-defined qline + */ +bool DoQLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types); +/** Add a config-defined kline + */ +bool DoKLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types); +/** Add a config-defined eline + */ +bool DoELine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types); + +/** Contains an ident and host split into two strings + */ +typedef std::pair<std::string, std::string> IdentHostPair; + +/** XLineManager is a class used to manage glines, klines, elines, zlines and qlines. + */ +class CoreExport XLineManager +{ + protected: + /** The owner/creator of this class + */ + InspIRCd* ServerInstance; + + /** This functor is used by the std::sort() function to keep glines in order + */ + static bool GSortComparison ( const GLine* one, const GLine* two ); + + /** This functor is used by the std::sort() function to keep elines in order + */ + static bool ESortComparison ( const ELine* one, const ELine* two ); + + /** This functor is used by the std::sort() function to keep zlines in order + */ + static bool ZSortComparison ( const ZLine* one, const ZLine* two ); + + /** This functor is used by the std::sort() function to keep klines in order + */ + static bool KSortComparison ( const KLine* one, const KLine* two ); + + /** This functor is used by the std::sort() function to keep qlines in order + */ + static bool QSortComparison ( const QLine* one, const QLine* two ); + public: + /* Lists for temporary lines with an expiry time */ + + /** Temporary KLines */ + std::vector<KLine*> klines; + + /** Temporary Glines */ + std::vector<GLine*> glines; + + /** Temporary Zlines */ + std::vector<ZLine*> zlines; + + /** Temporary QLines */ + std::vector<QLine*> qlines; + + /** Temporary ELines */ + std::vector<ELine*> elines; + + /* Seperate lists for perm XLines that isnt checked by expiry functions */ + + /** Permenant KLines */ + std::vector<KLine*> pklines; + + /** Permenant GLines */ + std::vector<GLine*> pglines; + + /** Permenant ZLines */ + std::vector<ZLine*> pzlines; + + /** Permenant QLines */ + std::vector<QLine*> pqlines; + + /** Permenant ELines */ + std::vector<ELine*> pelines; + + /** Constructor + * @param Instance A pointer to the creator object + */ + XLineManager(InspIRCd* Instance); + + /** Split an ident and host into two seperate strings. + * This allows for faster matching. + */ + IdentHostPair IdentSplit(const std::string &ident_and_host); + + /** Add a new GLine + * @param duration The duration of the line + * @param source The source of the line + * @param reason The reason for the line + * @param hostmask The hostmask + * @return True if the line was added successfully + */ + bool add_gline(long duration, const char* source, const char* reason, const char* hostmask); + + /** Add a new QLine + * @param duration The duration of the line + * @param source The source of the line + * @param reason The reason for the line + * @param nickname The nickmask + * @return True if the line was added successfully + */ + bool add_qline(long duration, const char* source, const char* reason, const char* nickname); + + /** Add a new ZLine + * @param duration The duration of the line + * @param source The source of the line + * @param reason The reason for the line + * @param ipaddr The IP mask + * @return True if the line was added successfully + */ + bool add_zline(long duration, const char* source, const char* reason, const char* ipaddr); + + /** Add a new KLine + * @param duration The duration of the line + * @param source The source of the line + * @param reason The reason for the line + * @param hostmask The hostmask + * @return True if the line was added successfully + */ + bool add_kline(long duration, const char* source, const char* reason, const char* hostmask); + + /** Add a new ELine + * @param duration The duration of the line + * @param source The source of the line + * @param reason The reason for the line + * @param hostmask The hostmask + * @return True if the line was added successfully + */ + bool add_eline(long duration, const char* source, const char* reason, const char* hostmask); + + /** Delete a GLine + * @param hostmask The host to remove + * @param simulate If this is true, don't actually remove the line, just return + * @return True if the line was deleted successfully + */ + bool del_gline(const char* hostmask, bool simulate = false); + + /** Delete a QLine + * @param nickname The nick to remove + * @param simulate If this is true, don't actually remove the line, just return + * @return True if the line was deleted successfully + */ + bool del_qline(const char* nickname, bool simulate = false); + + /** Delete a ZLine + * @param ipaddr The IP to remove + * @param simulate If this is true, don't actually remove the line, just return + * @return True if the line was deleted successfully + */ + bool del_zline(const char* ipaddr, bool simulate = false); + + /** Delete a KLine + * @param hostmask The host to remove + * @param simulate If this is true, don't actually remove the line, just return + * @return True if the line was deleted successfully + */ + bool del_kline(const char* hostmask, bool simulate = false); + + /** Delete a ELine + * @param hostmask The host to remove + * @param simulate If this is true, don't actually remove the line, just return + * @return True if the line was deleted successfully + */ + bool del_eline(const char* hostmask, bool simulate = false); + + /** Check if a nickname matches a QLine + * @return nick The nick to check against + * @return The reason for the line if there is a match, or NULL if there is no match + */ + QLine* matches_qline(const char* nick, bool permonly = false); + + /** Check if a hostname matches a GLine + * @param user The user to check against + * @return The reason for the line if there is a match, or NULL if there is no match + */ + GLine* matches_gline(userrec* user, bool permonly = false); + + /** Check if a IP matches a ZLine + * @param ipaddr The IP to check against + * @return The reason for the line if there is a match, or NULL if there is no match + */ + ZLine* matches_zline(const char* ipaddr, bool permonly = false); + + /** Check if a hostname matches a KLine + * @param user The user to check against + * @return The reason for the line if there is a match, or NULL if there is no match + */ + KLine* matches_kline(userrec* user, bool permonly = false); + + /** Check if a hostname matches a ELine + * @param user The user to check against + * @return The reason for the line if there is a match, or NULL if there is no match + */ + ELine* matches_exception(userrec* user, bool permonly = false); + + /** Expire any pending non-permenant lines + */ + void expire_lines(); + + /** Apply any new lines + * @param What The types of lines to apply, from the set + * APPLY_GLINES | APPLY_KLINES | APPLY_QLINES | APPLY_ZLINES | APPLY_ALL + * | APPLY_LOCAL_ONLY + */ + void apply_lines(const int What); + + /** Handle /STATS K + * @param user The username making the query + * @param results The string_list to receive the results + */ + void stats_k(userrec* user, string_list &results); + + /** Handle /STATS G + * @param user The username making the query + * @param results The string_list to receive the results + */ + void stats_g(userrec* user, string_list &results); + + /** Handle /STATS Q + * @param user The username making the query + * @param results The string_list to receive the results + */ + void stats_q(userrec* user, string_list &results); + + /** Handle /STATS Z + * @param user The username making the query + * @param results The string_list to receive the results + */ + void stats_z(userrec* user, string_list &results); + + /** Handle /STATS E + * @param user The username making the query + * @param results The string_list to receive the results + */ + void stats_e(userrec* user, string_list &results); + + /** Change creation time of a GLine + * @param host The hostname to change + * @param create_Time The new creation time + */ + void gline_set_creation_time(const char* host, time_t create_time); + + /** Change creation time of a QLine + * @param nick The nickmask to change + * @param create_Time The new creation time + */ + void qline_set_creation_time(const char* nick, time_t create_time); + + /** Change creation time of a ZLine + * @param ip The ipmask to change + * @param create_Time The new creation time + */ + void zline_set_creation_time(const char* ip, time_t create_time); + + /** Change creation time of a ELine + * @param host The hostname to change + * @param create_Time The new creation time + */ + void eline_set_creation_time(const char* host, time_t create_time); +}; + +#endif + |