1 /* +------------------------------------+
\r * | Inspire Internet Relay Chat Daemon |
\r * +------------------------------------+
\r *
\r * InspIRCd: (C) 2002-2007 InspIRCd Development Team
\r * See: http://www.inspircd.org/wiki/index.php/Credits
\r *
\r * This program is free but copyrighted software; see
\r * the file COPYING for details.
\r *
\r * ---------------------------------------------------
\r */
\r\r#ifndef INSPIRCD_CONFIGREADER
\r#define INSPIRCD_CONFIGREADER
\r\r/* handy defines */
\r\r/** Determines if a channel op is exempt from given mode m,
\r * in config of server instance s.
\r */
\r#define CHANOPS_EXEMPT(s, m) (s->Config->ExemptChanOps[(unsigned char)m])
\r\r#include <sstream>
\r#include <string>
\r#include <vector>
\r#include <map>
\r#include "inspircd.h"
\r#include "globals.h"
\r#include "modules.h"
\r#include "socketengine.h"
\r#include "socket.h"
\r\r/* Required forward definitions */
\rclass ServerConfig;
\rclass InspIRCd;
\rclass InspSocket;
\r\r/** Types of data in the core config
\r */
\renum ConfigDataType
\r{
\r DT_NOTHING = 0, /* No data */
\r DT_INTEGER = 1, /* Integer */
\r DT_CHARPTR = 2, /* Char pointer */
\r DT_BOOLEAN = 3, /* Boolean */
\r DT_ALLOW_NEWLINE = 128 /* New line characters allowed */
\r};
\r\r/** Holds a config value, either string, integer or boolean.
\r * Callback functions receive one or more of these, either on
\r * their own as a reference, or in a reference to a deque of them.
\r * The callback function can then alter the values of the ValueItem
\r * classes to validate the settings.
\r */
\rclass ValueItem
\r{
\r /** Actual data */
\r std::string v;
\r public:
\r /** Initialize with an int */
\r ValueItem(int value);
\r /** Initialize with a bool */
\r ValueItem(bool value);
\r /** Initialize with a char pointer */
\r ValueItem(char* value);
\r /** Change value to a char pointer */
\r void Set(char* value);
\r /** Change value to a const char pointer */
\r void Set(const char* val);
\r /** Change value to an int */
\r void Set(int value);
\r /** Get value as an int */
\r int GetInteger();
\r /** Get value as a string */
\r char* GetString();
\r /** Get value as a bool */
\r bool GetBool();
\r};
\r\r/** The base class of the container 'ValueContainer'
\r * used internally by the core to hold core values.
\r */
\rclass ValueContainerBase
\r{
\r public:
\r /** Constructor */
\r ValueContainerBase() { }
\r /** Destructor */
\r virtual ~ValueContainerBase() { }
\r};
\r\r/** ValueContainer is used to contain pointers to different
\r * core values such as the server name, maximum number of
\r * clients etc.
\r * It is specialized to hold a data type, then pointed at
\r * a value in the ServerConfig class. When the value has been
\r * read and validated, the Set method is called to write the
\r * value safely in a type-safe manner.
\r */
\rtemplate<typename T> class ValueContainer : public ValueContainerBase
\r{
\r /** Contained item */
\r T val;
\r public:
\r\r /** Initialize with nothing */
\r ValueContainer()
\r {
\r val = NULL;
\r }
\r\r /** Initialize with a value of type T */
\r ValueContainer(T Val)
\r {
\r val = Val;
\r }
\r\r /** Change value to type T of size s */
\r void Set(T newval, size_t s)
\r {
\r memcpy(val, newval, s);
\r }
\r};
\r\r/** A specialization of ValueContainer to hold a pointer to a bool
\r */
\rtypedef ValueContainer<bool*> ValueContainerBool;
\r\r/** A specialization of ValueContainer to hold a pointer to
\r * an unsigned int
\r */
\rtypedef ValueContainer<unsigned int*> ValueContainerUInt;
\r\r/** A specialization of ValueContainer to hold a pointer to
\r * a char array.
\r */
\rtypedef ValueContainer<char*> ValueContainerChar;
\r\r/** A specialization of ValueContainer to hold a pointer to
\r * an int
\r */
\rtypedef ValueContainer<int*> ValueContainerInt;
\r\r/** A set of ValueItems used by multi-value validator functions
\r */
\rtypedef std::deque<ValueItem> ValueList;
\r\r/** A callback for validating a single value
\r */
\rtypedef bool (*Validator)(ServerConfig* conf, const char*, const char*, ValueItem&);
\r/** A callback for validating multiple value entries
\r */
\rtypedef bool (*MultiValidator)(ServerConfig* conf, const char*, char**, ValueList&, int*);
\r/** A callback indicating the end of a group of entries
\r */
\rtypedef bool (*MultiNotify)(ServerConfig* conf, const char*);
\r\r/** Holds a core configuration item and its callbacks
\r */
\rstruct InitialConfig
\r{
\r /** Tag name */
\r char* tag;
\r /** Value name */
\r char* value;
\r /** Default, if not defined */
\r char* default_value;
\r /** Value containers */
\r ValueContainerBase* val;
\r /** Data types */
\r ConfigDataType datatype;
\r /** Validation function */
\r Validator validation_function;
\r};
\r\r/** Holds a core configuration item and its callbacks
\r * where there may be more than one item
\r */
\rstruct MultiConfig
\r{
\r /** Tag name */
\r const char* tag;
\r /** One or more items within tag */
\r char* items[13];
\r /** One or more defaults for items within tags */
\r char* items_default[13];
\r /** One or more data types */
\r int datatype[13];
\r /** Initialization function */
\r MultiNotify init_function;
\r /** Validation function */
\r MultiValidator validation_function;
\r /** Completion function */
\r MultiNotify finish_function;
\r};
\r\r/** A set of oper types
\r */
\rtypedef std::map<irc::string,char*> opertype_t;
\r\r/** A Set of oper classes
\r */
\rtypedef std::map<irc::string,char*> operclass_t;
\r\r\r/** This class holds the bulk of the runtime configuration for the ircd.
\r * It allows for reading new config values, accessing configuration files,
\r * and storage of the configuration data needed to run the ircd, such as
\r * the servername, connect classes, /ADMIN data, MOTDs and filenames etc.
\r */
\rclass CoreExport ServerConfig : public Extensible
\r{
\r private:
\r /** Creator/owner pointer
\r */
\r InspIRCd* ServerInstance;
\r\r /** This variable holds the names of all
\r * files included from the main one. This
\r * is used to make sure that no files are
\r * recursively included.
\r */
\r std::vector<std::string> include_stack;
\r\r /** This private method processes one line of
\r * configutation, appending errors to errorstream
\r * and setting error if an error has occured.
\r */
\r bool ParseLine(ConfigDataHash &target, std::string &line, long linenumber, std::ostringstream &errorstream);
\r \r /** Process an include directive
\r */
\r bool DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream);
\r\r /** Check that there is only one of each configuration item
\r */
\r bool CheckOnce(char* tag, bool bail, userrec* user);
\r \r public:
\r\r InspIRCd* GetInstance();
\r \r /** This holds all the information in the config file,
\r * it's indexed by tag name to a vector of key/values.
\r */
\r ConfigDataHash config_data;
\r\r /** Max number of WhoWas entries per user.
\r */
\r int WhoWasGroupSize;
\r\r /** Max number of cumulative user-entries in WhoWas.
\r * When max reached and added to, push out oldest entry FIFO style.
\r */
\r int WhoWasMaxGroups;
\r\r /** Max seconds a user is kept in WhoWas before being pruned.
\r */
\r int WhoWasMaxKeep;
\r\r /** Holds the server name of the local server
\r * as defined by the administrator.
\r */
\r char ServerName[MAXBUF];
\r\r /** Notice to give to users when they are Xlined
\r */
\r char MoronBanner[MAXBUF];
\r \r /* Holds the network name the local server
\r * belongs to. This is an arbitary field defined
\r * by the administrator.
\r */
\r char Network[MAXBUF];
\r\r /** Holds the description of the local server
\r * as defined by the administrator.
\r */
\r char ServerDesc[MAXBUF];
\r\r /** Holds the admin's name, for output in
\r * the /ADMIN command.
\r */
\r char AdminName[MAXBUF];
\r\r /** Holds the email address of the admin,
\r * for output in the /ADMIN command.
\r */
\r char AdminEmail[MAXBUF];
\r\r /** Holds the admin's nickname, for output
\r * in the /ADMIN command
\r */
\r char AdminNick[MAXBUF];
\r\r /** The admin-configured /DIE password
\r */
\r char diepass[MAXBUF];
\r\r /** The admin-configured /RESTART password
\r */
\r char restartpass[MAXBUF];
\r\r /** The pathname and filename of the message of the
\r * day file, as defined by the administrator.
\r */
\r char motd[MAXBUF];
\r\r /** The pathname and filename of the rules file,
\r * as defined by the administrator.
\r */
\r char rules[MAXBUF];
\r\r /** The quit prefix in use, or an empty string
\r */
\r char PrefixQuit[MAXBUF];
\r\r /** The quit suffix in use, or an empty string
\r */
\r char SuffixQuit[MAXBUF];
\r\r /** The fixed quit message in use, or an empty string
\r */
\r char FixedQuit[MAXBUF];
\r\r /** The last string found within a <die> tag, or
\r * an empty string.
\r */
\r char DieValue[MAXBUF];
\r\r /** The DNS server to use for DNS queries
\r */
\r char DNSServer[MAXBUF];
\r\r /** This variable contains a space-seperated list
\r * of commands which are disabled by the
\r * administrator of the server for non-opers.
\r */
\r char DisabledCommands[MAXBUF];
\r\r /** The full path to the modules directory.
\r * This is either set at compile time, or
\r * overridden in the configuration file via
\r * the <options> tag.
\r */
\r char ModPath[1024];
\r\r /** The full pathname to the executable, as
\r * given in argv[0] when the program starts.
\r */
\r char MyExecutable[1024];
\r\r /** The file handle of the logfile. If this
\r * value is NULL, the log file is not open,
\r * probably due to a permissions error on
\r * startup (this should not happen in normal
\r * operation!).
\r */
\r FILE *log_file;
\r\r /** If this value is true, the owner of the
\r * server specified -nofork on the command
\r * line, causing the daemon to stay in the
\r * foreground.
\r */
\r bool nofork;
\r \r /** If this value if true then all log
\r * messages will be output, regardless of
\r * the level given in the config file.
\r * This is set with the -debug commandline
\r * option.
\r */
\r bool forcedebug;
\r \r /** If this is true then log output will be
\r * written to the logfile. This is the default.
\r * If you put -nolog on the commandline then
\r * the logfile will not be written.
\r * This is meant to be used in conjunction with
\r * -debug for debugging without filling up the
\r * hard disk.
\r */
\r bool writelog;
\r\r /** If this value is true, halfops have been
\r * enabled in the configuration file.
\r */
\r bool AllowHalfop;
\r\r /** If this is set to true, then mode lists (e.g
\r * MODE #chan b) are hidden from unprivileged
\r * users.
\r */
\r bool HideModeLists[256];
\r\r /** If this is set to true, then channel operators
\r * are exempt from this channel mode. Used for +Sc etc.
\r */
\r bool ExemptChanOps[256];
\r\r /** The number of seconds the DNS subsystem
\r * will wait before timing out any request.
\r */
\r int dns_timeout;
\r\r /** The size of the read() buffer in the user
\r * handling code, used to read data into a user's
\r * recvQ.
\r */
\r int NetBufferSize;
\r\r /** The value to be used for listen() backlogs
\r * as default.
\r */
\r int MaxConn;
\r\r /** The soft limit value assigned to the irc server.
\r * The IRC server will not allow more than this
\r * number of local users.
\r */
\r unsigned int SoftLimit;
\r\r /** Maximum number of targets for a multi target command
\r * such as PRIVMSG or KICK
\r */
\r unsigned int MaxTargets;
\r\r /** The maximum number of /WHO results allowed
\r * in any single /WHO command.
\r */
\r int MaxWhoResults;
\r\r /** True if the DEBUG loglevel is selected.
\r */
\r int debugging;
\r\r /** The loglevel in use by the IRC server
\r */
\r int LogLevel;
\r\r /** How many seconds to wait before exiting
\r * the program when /DIE is correctly issued.
\r */
\r int DieDelay;
\r\r /** True if we're going to hide netsplits as *.net *.split for non-opers
\r */
\r bool HideSplits;
\r\r /** True if we're going to hide ban reasons for non-opers (e.g. G-Lines,
\r * K-Lines, Z-Lines)
\r */
\r bool HideBans;
\r\r /** Announce invites to the channel with a server notice
\r */
\r bool AnnounceInvites;
\r\r /** If this is enabled then operators will
\r * see invisible (+i) channels in /whois.
\r */
\r bool OperSpyWhois;
\r\r /** Set to a non-empty string to obfuscate the server name of users in WHOIS
\r */
\r char HideWhoisServer[MAXBUF];
\r\r /** Set to a non empty string to obfuscate nicknames prepended to a KILL.
\r */
\r char HideKillsServer[MAXBUF];
\r\r /** The MOTD file, cached in a file_cache type.
\r */
\r file_cache MOTD;
\r\r /** The RULES file, cached in a file_cache type.
\r */
\r file_cache RULES;
\r\r /** The full pathname and filename of the PID
\r * file as defined in the configuration.
\r */
\r char PID[1024];
\r\r /** The connect classes in use by the IRC server.
\r */
\r ClassVector Classes;
\r\r /** A list of module names (names only, no paths)
\r * which are currently loaded by the server.
\r */
\r std::vector<std::string> module_names;
\r\r /** A list of the classes for listening client ports
\r */
\r std::vector<ListenSocket*> ports;
\r\r /** Boolean sets of which modules implement which functions
\r */
\r char implement_lists[255][255];
\r\r /** Global implementation list
\r */
\r char global_implementation[255];
\r\r /** A list of ports claimed by IO Modules
\r */
\r std::map<int,Module*> IOHookModule;
\r\r std::map<InspSocket*, Module*> SocketIOHookModule;
\r\r /** The 005 tokens of this server (ISUPPORT)
\r * populated/repopulated upon loading or unloading
\r * modules.
\r */
\r std::string data005;
\r\r /** isupport strings
\r */
\r std::vector<std::string> isupport;
\r\r /** STATS characters in this list are available
\r * only to operators.
\r */
\r char UserStats[MAXBUF];
\r \r /** The path and filename of the ircd.log file
\r */
\r std::string logpath;
\r\r /** Default channel modes
\r */
\r char DefaultModes[MAXBUF];
\r\r /** Custom version string, which if defined can replace the system info in VERSION.
\r */
\r char CustomVersion[MAXBUF];
\r\r /** List of u-lined servers
\r */
\r std::map<irc::string, bool> ulines;
\r\r /** Max banlist sizes for channels (the std::string is a glob)
\r */
\r std::map<std::string, int> maxbans;
\r\r /** Directory where the inspircd binary resides
\r */
\r std::string MyDir;
\r\r /** If set to true, no user DNS lookups are to be performed
\r */
\r bool NoUserDns;
\r\r /** If set to true, provide syntax hints for unknown commands
\r */
\r bool SyntaxHints;
\r\r /** If set to true, users appear to quit then rejoin when their hosts change.
\r * This keeps clients synchronized properly.
\r */
\r bool CycleHosts;
\r\r /** If set to true, prefixed channel NOTICEs and PRIVMSGs will have the prefix
\r * added to the outgoing text for undernet style msg prefixing.
\r */
\r bool UndernetMsgPrefix;
\r\r /** If set to true, the full nick!user@host will be shown in the TOPIC command
\r * for who set the topic last. If false, only the nick is shown.
\r */
\r bool FullHostInTopic;
\r\r /** All oper type definitions from the config file
\r */
\r opertype_t opertypes;
\r\r /** All oper class definitions from the config file
\r */
\r operclass_t operclass;
\r\r /** Saved argv from startup
\r */
\r char** argv;
\r\r /** Saved argc from startup
\r */
\r int argc;
\r\r /** Max channels per user
\r */
\r unsigned int MaxChans;
\r\r /** Oper max channels per user
\r */
\r unsigned int OperMaxChans;
\r\r /** Construct a new ServerConfig
\r */
\r ServerConfig(InspIRCd* Instance);
\r\r /** Clears the include stack in preperation for a Read() call.
\r */
\r void ClearStack();
\r\r /** Update the 005 vector
\r */
\r void Update005();
\r\r /** Send the 005 numerics (ISUPPORT) to a user
\r */
\r void Send005(userrec* user);
\r\r /** Read the entire configuration into memory
\r * and initialize this class. All other methods
\r * should be used only by the core.
\r */
\r void Read(bool bail, userrec* user);
\r\r /** Read a file into a file_cache object
\r */
\r bool ReadFile(file_cache &F, const char* fname);
\r\r /** Report a configuration error given in errormessage.
\r * @param bail If this is set to true, the error is sent to the console, and the program exits
\r * @param user If this is set to a non-null value, and bail is false, the errors are spooled to
\r * this user as SNOTICEs.
\r * If the parameter is NULL, the messages are spooled to all users via WriteOpers as SNOTICEs.
\r */
\r void ReportConfigError(const std::string &errormessage, bool bail, userrec* user);
\r\r /** Load 'filename' into 'target', with the new config parser everything is parsed into
\r * tag/key/value at load-time rather than at read-value time.
\r */
\r bool LoadConf(ConfigDataHash &target, const char* filename, std::ostringstream &errorstream);
\r\r /** Load 'filename' into 'target', with the new config parser everything is parsed into
\r * tag/key/value at load-time rather than at read-value time.
\r */
\r bool LoadConf(ConfigDataHash &target, const std::string &filename, std::ostringstream &errorstream);
\r \r /* Both these return true if the value existed or false otherwise */
\r \r /** Writes 'length' chars into 'result' as a string
\r */
\r bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds = false);
\r /** Writes 'length' chars into 'result' as a string
\r */
\r bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, char* result, int length, bool allow_linefeeds = false);
\r\r /** Writes 'length' chars into 'result' as a string
\r */
\r bool ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, std::string &result, bool allow_linefeeds = false);
\r /** Writes 'length' chars into 'result' as a string
\r */
\r 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);
\r \r /** Tries to convert the value to an integer and write it to 'result'
\r */
\r bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, int index, int &result);
\r /** Tries to convert the value to an integer and write it to 'result'
\r */
\r bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, int &result);
\r /** Tries to convert the value to an integer and write it to 'result'
\r */
\r bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, int &result);
\r /** Tries to convert the value to an integer and write it to 'result'
\r */
\r bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, int &result);
\r \r /** Returns true if the value exists and has a true value, false otherwise
\r */
\r bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, int index);
\r /** Returns true if the value exists and has a true value, false otherwise
\r */
\r bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index);
\r /** Returns true if the value exists and has a true value, false otherwise
\r */
\r bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, int index);
\r /** Returns true if the value exists and has a true value, false otherwise
\r */
\r bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index);
\r \r /** Returns the number of occurences of tag in the config file
\r */
\r int ConfValueEnum(ConfigDataHash &target, const char* tag);
\r /** Returns the number of occurences of tag in the config file
\r */
\r int ConfValueEnum(ConfigDataHash &target, const std::string &tag);
\r \r /** Returns the numbers of vars inside the index'th 'tag in the config file
\r */
\r int ConfVarEnum(ConfigDataHash &target, const char* tag, int index);
\r /** Returns the numbers of vars inside the index'th 'tag in the config file
\r */
\r int ConfVarEnum(ConfigDataHash &target, const std::string &tag, int index);
\r \r /** Get a pointer to the module which has hooked the given port.
\r * @parameter port Port number
\r * @return Returns a pointer to the hooking module, or NULL
\r */
\r Module* GetIOHook(int port);
\r\r /** Hook a module to a client port, so that it can receive notifications
\r * of low-level port activity.
\r * @param port The port number
\r * @param Module the module to hook to the port
\r * @return True if the hook was successful.
\r */
\r bool AddIOHook(int port, Module* iomod);
\r\r /** Delete a module hook from a client port.
\r * @param port The port to detatch from
\r * @return True if successful
\r */
\r bool DelIOHook(int port);
\r \r /** Get a pointer to the module which has hooked the given InspSocket class.
\r * @parameter port Port number
\r * @return Returns a pointer to the hooking module, or NULL
\r */
\r Module* GetIOHook(InspSocket* is);
\r\r /** Hook a module to an InspSocket class, so that it can receive notifications
\r * of low-level socket activity.
\r * @param iomod The module to hook to the socket
\r * @param is The InspSocket to attach to
\r * @return True if the hook was successful.
\r */
\r bool AddIOHook(Module* iomod, InspSocket* is);
\r\r /** Delete a module hook from an InspSocket.
\r * @param is The InspSocket to detatch from.
\r * @return True if the unhook was successful
\r */
\r bool DelIOHook(InspSocket* is);
\r\r /** Returns the fully qualified path to the inspircd directory
\r * @return The full program directory
\r */
\r std::string GetFullProgDir();
\r\r /** Returns true if a directory is valid (within the modules directory).
\r * @param dirandfile The directory and filename to check
\r * @return True if the directory is valid
\r */
\r static bool DirValid(const char* dirandfile);
\r\r /** Clean a filename, stripping the directories (and drives) from string.
\r * @param name Directory to tidy
\r * @return The cleaned filename
\r */
\r static char* CleanFilename(char* name);
\r\r /** Check if a file exists.
\r * @param file The full path to a file
\r * @return True if the file exists and is readable.
\r */
\r static bool FileExists(const char* file);
\r \r};
\r\r/** Initialize the disabled commands list
\r */
\rCoreExport bool InitializeDisabledCommands(const char* data, InspIRCd* ServerInstance);
\r\r/** Initialize the oper types
\r */
\rbool InitTypes(ServerConfig* conf, const char* tag);
\r\r/** Initialize the oper classes
\r */
\rbool InitClasses(ServerConfig* conf, const char* tag);
\r\r/** Initialize an oper type
\r */
\rbool DoType(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
\r\r/** Initialize an oper class
\r */
\rbool DoClass(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
\r\r/** Finish initializing the oper types and classes
\r */
\rbool DoneClassesAndTypes(ServerConfig* conf, const char* tag);
\r\r#endif
\r\r