1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd: (C) 2002-2008 InspIRCd Development Team
6 * See: http://www.inspircd.org/wiki/index.php/Credits
8 * This program is free but copyrighted software; see
9 * the file COPYING for details.
11 * ---------------------------------------------------
14 #ifndef INSPIRCD_CONFIGREADER
15 #define INSPIRCD_CONFIGREADER
19 /** Determines if a channel op is exempt from given mode m,
20 * in config of server instance s.
22 #define CHANOPS_EXEMPT(s, m) (s->Config->ExemptChanOps[(unsigned char)m])
30 #include "socketengine.h"
33 /* Required forward definitions */
38 /** Types of data in the core config
42 DT_NOTHING = 0, /* No data */
43 DT_INTEGER = 1, /* Integer */
44 DT_CHARPTR = 2, /* Char pointer */
45 DT_BOOLEAN = 3, /* Boolean */
46 DT_HOSTNAME = 4, /* Hostname syntax */
47 DT_NOSPACES = 5, /* No spaces */
48 DT_IPADDRESS = 6, /* IP address (v4, v6) */
49 DT_CHANNEL = 7, /* Channel name */
50 DT_ALLOW_WILD = 64, /* Allow wildcards/CIDR in DT_IPADDRESS */
51 DT_ALLOW_NEWLINE = 128, /* New line characters allowed in DT_CHARPTR */
52 DT_BOOTONLY = 256 /* Can only be set on startup, not on rehash */
55 /** The maximum number of values in a core configuration tag. Can be increased if needed.
57 #define MAX_VALUES_PER_TAG 18
59 /** Holds a config value, either string, integer or boolean.
60 * Callback functions receive one or more of these, either on
61 * their own as a reference, or in a reference to a deque of them.
62 * The callback function can then alter the values of the ValueItem
63 * classes to validate the settings.
70 /** Initialize with an int */
72 /** Initialize with a bool */
73 ValueItem(bool value);
74 /** Initialize with a char pointer */
75 ValueItem(const char* value);
76 /** Change value to a char pointer */
77 void Set(const char* val);
78 /** Change value to an int */
80 /** Get value as an int */
82 /** Get value as a string */
84 /** Get value as a bool */
88 /** The base class of the container 'ValueContainer'
89 * used internally by the core to hold core values.
91 class ValueContainerBase
95 ValueContainerBase() { }
97 virtual ~ValueContainerBase() { }
100 /** ValueContainer is used to contain pointers to different
101 * core values such as the server name, maximum number of
103 * It is specialized to hold a data type, then pointed at
104 * a value in the ServerConfig class. When the value has been
105 * read and validated, the Set method is called to write the
106 * value safely in a type-safe manner.
108 template<typename T> class ValueContainer : public ValueContainerBase
110 /** Contained item */
114 /** Initialize with nothing */
120 /** Initialize with a value of type T */
121 ValueContainer(T Val)
126 /** Change value to type T of size s */
127 void Set(T newval, size_t s)
129 memcpy(val, newval, s);
133 /** A specialization of ValueContainer to hold a pointer to a bool
135 typedef ValueContainer<bool*> ValueContainerBool;
137 /** A specialization of ValueContainer to hold a pointer to
140 typedef ValueContainer<unsigned int*> ValueContainerUInt;
142 /** A specialization of ValueContainer to hold a pointer to
145 typedef ValueContainer<char*> ValueContainerChar;
147 /** A specialization of ValueContainer to hold a pointer to
150 typedef ValueContainer<int*> ValueContainerInt;
152 /** A specialization of ValueContainer to hold a pointer to
155 typedef ValueContainer<size_t*> ValueContainerST;
157 /** A set of ValueItems used by multi-value validator functions
159 typedef std::deque<ValueItem> ValueList;
161 /** A callback for validating a single value
163 typedef bool (*Validator)(ServerConfig* conf, const char*, const char*, ValueItem&);
164 /** A callback for validating multiple value entries
166 typedef bool (*MultiValidator)(ServerConfig* conf, const char*, char**, ValueList&, int*);
167 /** A callback indicating the end of a group of entries
169 typedef bool (*MultiNotify)(ServerConfig* conf, const char*);
171 /** Holds a core configuration item and its callbacks
179 /** Default, if not defined */
180 const char* default_value;
181 /** Value containers */
182 ValueContainerBase* val;
185 /** Validation function */
186 Validator validation_function;
189 /** Represents a deprecated configuration tag.
199 /** Reason for deprecation
204 /** Holds a core configuration item and its callbacks
205 * where there may be more than one item
211 /** One or more items within tag */
212 const char* items[MAX_VALUES_PER_TAG];
213 /** One or more defaults for items within tags */
214 const char* items_default[MAX_VALUES_PER_TAG];
215 /** One or more data types */
216 int datatype[MAX_VALUES_PER_TAG];
217 /** Initialization function */
218 MultiNotify init_function;
219 /** Validation function */
220 MultiValidator validation_function;
221 /** Completion function */
222 MultiNotify finish_function;
225 /** A set of oper types
227 typedef std::map<irc::string,char*> opertype_t;
229 /** Holds an oper class.
231 struct operclass_data : public Extensible
233 /** Command list for the class
236 /** Channel mode list for the class
239 /** User mode list for the class
244 /** A Set of oper classes
246 typedef std::map<irc::string, operclass_data> operclass_t;
248 /** Defines the server's length limits on various length-limited
249 * items such as topics, nicknames, channel names etc.
251 class ServerLimits : public Extensible
254 /** Maximum nickname length */
256 /** Maximum channel length */
258 /** Maximum number of modes per line */
260 /** Maximum length of ident, not including ~ etc */
262 /** Maximum length of a quit message */
264 /** Maximum topic length */
266 /** Maximum kick message length */
268 /** Maximum GECOS (real name) length */
270 /** Maximum away message length */
273 /** Creating the class initialises it to the defaults
274 * as in 1.1's ./configure script. Reading other values
275 * from the config will change these values.
277 ServerLimits() : NickMax(31), ChanMax(64), MaxModes(20), IdentMax(12), MaxQuit(255), MaxTopic(307), MaxKick(255), MaxGecos(128), MaxAway(200)
281 /** Finalises the settings by adding one. This allows for them to be used as-is
282 * without a 'value+1' when using the std::string assignment methods etc.
297 /** This class holds the bulk of the runtime configuration for the ircd.
298 * It allows for reading new config values, accessing configuration files,
299 * and storage of the configuration data needed to run the ircd, such as
300 * the servername, connect classes, /ADMIN data, MOTDs and filenames etc.
302 class CoreExport ServerConfig : public Extensible
305 /** Creator/owner pointer
307 InspIRCd* ServerInstance;
309 /** This variable holds the names of all
310 * files included from the main one. This
311 * is used to make sure that no files are
312 * recursively included.
314 std::vector<std::string> include_stack;
316 /** This private method processes one line of
317 * configutation, appending errors to errorstream
318 * and setting error if an error has occured.
320 bool ParseLine(ConfigDataHash &target, const std::string &filename, std::string &line, long &linenumber, std::ostringstream &errorstream);
322 /** Check that there is only one of each configuration item
324 bool CheckOnce(const char* tag, ConfigDataHash &newconf);
327 /** Process an include executable directive
329 bool DoPipe(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream);
331 /** Process an include file directive
333 bool DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream);
335 /** User that is currently performing a rehash, needed because the
336 * rehash code is now threaded and needs to know who to give errors and feedback to.
338 std::string RehashUserUID;
340 /** Rehash parameter, as above
342 std::string RehashParameter;
344 /** Error stream, contains error output from any failed configuration parsing.
346 std::ostringstream errstr;
348 /** Holds the new configuration when a rehash occurs so we dont overwrite the existing
349 * working config with a broken one without checking it first and swapping pointers.
351 ConfigDataHash newconfig;
353 /** Set of included files. Do we use this any more?
355 std::map<std::string, std::istream*> IncludedFiles;
357 /** Used to indicate who we announce invites to on a channel */
358 enum InviteAnnounceState { INVITE_ANNOUNCE_NONE, INVITE_ANNOUNCE_ALL, INVITE_ANNOUNCE_OPS, INVITE_ANNOUNCE_DYNAMIC };
360 /** Pointer to function that validates dns server addresses (can be changed depending on platform) */
361 Validator DNSServerValidator;
363 /** Returns the creator InspIRCd pointer
365 InspIRCd* GetInstance();
367 /** Not used any more as it is named, can probably be removed or renamed.
371 /** This holds all the information in the config file,
372 * it's indexed by tag name to a vector of key/values.
374 ConfigDataHash config_data;
376 /** Length limits, see definition of ServerLimits class
380 /** Clones CIDR range for ipv4 (0-32)
381 * Defaults to 32 (checks clones on all IPs seperately)
385 /** Clones CIDR range for ipv6 (0-128)
386 * Defaults to 128 (checks on all IPs seperately)
390 /** Max number of WhoWas entries per user.
394 /** Max number of cumulative user-entries in WhoWas.
395 * When max reached and added to, push out oldest entry FIFO style.
399 /** Max seconds a user is kept in WhoWas before being pruned.
403 /** Holds the server name of the local server
404 * as defined by the administrator.
406 char ServerName[MAXBUF];
408 /** Notice to give to users when they are Xlined
410 char MoronBanner[MAXBUF];
412 /* Holds the network name the local server
413 * belongs to. This is an arbitary field defined
414 * by the administrator.
416 char Network[MAXBUF];
418 /** Holds the description of the local server
419 * as defined by the administrator.
421 char ServerDesc[MAXBUF];
423 /** Holds the admin's name, for output in
424 * the /ADMIN command.
426 char AdminName[MAXBUF];
428 /** Holds the email address of the admin,
429 * for output in the /ADMIN command.
431 char AdminEmail[MAXBUF];
433 /** Holds the admin's nickname, for output
434 * in the /ADMIN command
436 char AdminNick[MAXBUF];
438 /** The admin-configured /DIE password
440 char diepass[MAXBUF];
442 /** The admin-configured /RESTART password
444 char restartpass[MAXBUF];
446 /** The hash method for *BOTH* the die and restart passwords.
448 char powerhash[MAXBUF];
450 /** The pathname and filename of the message of the
451 * day file, as defined by the administrator.
455 /** The pathname and filename of the rules file,
456 * as defined by the administrator.
460 /** The quit prefix in use, or an empty string
462 char PrefixQuit[MAXBUF];
464 /** The quit suffix in use, or an empty string
466 char SuffixQuit[MAXBUF];
468 /** The fixed quit message in use, or an empty string
470 char FixedQuit[MAXBUF];
472 /** The part prefix in use, or an empty string
474 char PrefixPart[MAXBUF];
476 /** The part suffix in use, or an empty string
478 char SuffixPart[MAXBUF];
480 /** The fixed part message in use, or an empty string
482 char FixedPart[MAXBUF];
484 /** The last string found within a <die> tag, or
487 char DieValue[MAXBUF];
489 /** The DNS server to use for DNS queries
491 char DNSServer[MAXBUF];
493 /** Pretend disabled commands don't exist.
495 bool DisabledDontExist;
497 /** This variable contains a space-seperated list
498 * of commands which are disabled by the
499 * administrator of the server for non-opers.
501 char DisabledCommands[MAXBUF];
503 /** This variable identifies which usermodes have been diabled.
506 char DisabledUModes[64];
508 /** This variable identifies which chanmodes have been disabled.
510 char DisabledCModes[64];
512 /** The full path to the modules directory.
513 * This is either set at compile time, or
514 * overridden in the configuration file via
519 /** The full pathname to the executable, as
520 * given in argv[0] when the program starts.
522 char MyExecutable[1024];
524 /** The file handle of the logfile. If this
525 * value is NULL, the log file is not open,
526 * probably due to a permissions error on
527 * startup (this should not happen in normal
532 /** If this value is true, the owner of the
533 * server specified -nofork on the command
534 * line, causing the daemon to stay in the
539 /** If this value if true then all log
540 * messages will be output, regardless of
541 * the level given in the config file.
542 * This is set with the -debug commandline
547 /** If this is true then log output will be
548 * written to the logfile. This is the default.
549 * If you put -nolog on the commandline then
550 * the logfile will not be written.
551 * This is meant to be used in conjunction with
552 * -debug for debugging without filling up the
557 /** If this value is true, halfops have been
558 * enabled in the configuration file.
562 /** If this is set to true, then mode lists (e.g
563 * MODE #chan b) are hidden from unprivileged
566 bool HideModeLists[256];
568 /** If this is set to true, then channel operators
569 * are exempt from this channel mode. Used for +Sc etc.
571 bool ExemptChanOps[256];
573 /** The number of seconds the DNS subsystem
574 * will wait before timing out any request.
578 /** The size of the read() buffer in the user
579 * handling code, used to read data into a user's
584 /** The value to be used for listen() backlogs
589 /** The soft limit value assigned to the irc server.
590 * The IRC server will not allow more than this
591 * number of local users.
593 unsigned int SoftLimit;
595 /** Maximum number of targets for a multi target command
596 * such as PRIVMSG or KICK
598 unsigned int MaxTargets;
600 /** The maximum number of /WHO results allowed
601 * in any single /WHO command.
605 /** True if the DEBUG loglevel is selected.
609 /** How many seconds to wait before exiting
610 * the program when /DIE is correctly issued.
614 /** True if we're going to hide netsplits as *.net *.split for non-opers
618 /** True if we're going to hide ban reasons for non-opers (e.g. G-Lines,
623 /** Announce invites to the channel with a server notice
625 InviteAnnounceState AnnounceInvites;
627 /** If this is enabled then operators will
628 * see invisible (+i) channels in /whois.
632 /** Set to a non-empty string to obfuscate the server name of users in WHOIS
634 char HideWhoisServer[MAXBUF];
636 /** Set to a non empty string to obfuscate nicknames prepended to a KILL.
638 char HideKillsServer[MAXBUF];
640 /** The MOTD file, cached in a file_cache type.
644 /** The RULES file, cached in a file_cache type.
648 /** The full pathname and filename of the PID
649 * file as defined in the configuration.
653 /** The connect classes in use by the IRC server.
657 /** A list of the classes for listening ports
659 std::vector<ListenSocketBase *> ports;
661 /** The 005 tokens of this server (ISUPPORT)
662 * populated/repopulated upon loading or unloading
669 std::vector<std::string> isupport;
671 /** STATS characters in this list are available
674 char UserStats[MAXBUF];
676 /** The path and filename of the ircd.log file
680 /** Default channel modes
682 char DefaultModes[MAXBUF];
684 /** Custom version string, which if defined can replace the system info in VERSION.
686 char CustomVersion[MAXBUF];
688 /** List of u-lined servers
690 std::map<irc::string, bool> ulines;
692 /** Max banlist sizes for channels (the std::string is a glob)
694 std::map<std::string, int> maxbans;
696 /** Directory where the inspircd binary resides
700 /** If set to true, no user DNS lookups are to be performed
704 /** If set to true, provide syntax hints for unknown commands
708 /** If set to true, users appear to quit then rejoin when their hosts change.
709 * This keeps clients synchronized properly.
713 /** If set to true, prefixed channel NOTICEs and PRIVMSGs will have the prefix
714 * added to the outgoing text for undernet style msg prefixing.
716 bool UndernetMsgPrefix;
718 /** If set to true, the full nick!user@host will be shown in the TOPIC command
719 * for who set the topic last. If false, only the nick is shown.
721 bool FullHostInTopic;
723 /** All oper type definitions from the config file
725 opertype_t opertypes;
727 /** All oper class definitions from the config file
729 operclass_t operclass;
731 /** Saved argv from startup
735 /** Saved argc from startup
739 /** Max channels per user
741 unsigned int MaxChans;
743 /** Oper max channels per user
745 unsigned int OperMaxChans;
747 /** TS6-like server ID.
748 * NOTE: 000...999 are usable for InspIRCd servers. This
749 * makes code simpler. 0AA, 1BB etc with letters are reserved
754 /** True if we have been told to run the testsuite from the commandline,
755 * rather than entering the mainloop.
759 /** Construct a new ServerConfig
761 ServerConfig(InspIRCd* Instance);
763 /** Clears the include stack in preperation for a Read() call.
767 /** Get server ID as string with required leading zeroes
769 std::string GetSID();
771 /** Update the 005 vector
775 /** Send the 005 numerics (ISUPPORT) to a user
777 void Send005(User* user);
779 /** Read the entire configuration into memory
780 * and initialize this class. All other methods
781 * should be used only by the core.
783 void Read(bool bail, const std::string &useruid);
785 /** Read a file into a file_cache object
787 bool ReadFile(file_cache &F, const char* fname);
789 /* Returns true if the given string starts with a windows drive letter
791 bool StartsWithWindowsDriveLetter(const std::string &path);
793 /** Report a configuration error given in errormessage.
794 * @param bail If this is set to true, the error is sent to the console, and the program exits
795 * @param useruid If this is set to a non-empty value which is a valid UID, and bail is false,
796 * the errors are spooled to this user as SNOTICEs.
797 * If the parameter is not a valid UID, the messages are spooled to all opers.
799 void ReportConfigError(const std::string &errormessage, bool bail, const std::string &useruid);
801 /** Load 'filename' into 'target', with the new config parser everything is parsed into
802 * tag/key/value at load-time rather than at read-value time.
804 bool LoadConf(ConfigDataHash &target, FILE* &conf, const char* filename, std::ostringstream &errorstream);
806 /** Load 'filename' into 'target', with the new config parser everything is parsed into
807 * tag/key/value at load-time rather than at read-value time.
809 bool LoadConf(ConfigDataHash &target, FILE* &conf, const std::string &filename, std::ostringstream &errorstream);
811 /** Writes 'length' chars into 'result' as a string
813 bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds = false);
815 /** Writes 'length' chars into 'result' as a string
817 bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, char* result, int length, bool allow_linefeeds = false);
819 /** Writes 'length' chars into 'result' as a string
821 bool ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, std::string &result, bool allow_linefeeds = false);
823 /** Writes 'length' chars into 'result' as a string
825 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);
827 /** Tries to convert the value to an integer and write it to 'result'
829 bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, int index, int &result);
831 /** Tries to convert the value to an integer and write it to 'result'
833 bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, int &result);
835 /** Tries to convert the value to an integer and write it to 'result'
837 bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, int &result);
839 /** Tries to convert the value to an integer and write it to 'result'
841 bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, int &result);
843 /** Returns true if the value exists and has a true value, false otherwise
845 bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, int index);
847 /** Returns true if the value exists and has a true value, false otherwise
849 bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index);
851 /** Returns true if the value exists and has a true value, false otherwise
853 bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, int index);
855 /** Returns true if the value exists and has a true value, false otherwise
857 bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index);
859 /** Returns the number of occurences of tag in the config file
861 int ConfValueEnum(ConfigDataHash &target, const char* tag);
862 /** Returns the number of occurences of tag in the config file
864 int ConfValueEnum(ConfigDataHash &target, const std::string &tag);
866 /** Returns the numbers of vars inside the index'th 'tag in the config file
868 int ConfVarEnum(ConfigDataHash &target, const char* tag, int index);
869 /** Returns the numbers of vars inside the index'th 'tag in the config file
871 int ConfVarEnum(ConfigDataHash &target, const std::string &tag, int index);
873 /** Validates a hostname value, throwing ConfigException if it is not valid
875 void ValidateHostname(const char* p, const std::string &tag, const std::string &val);
877 /** Validates an IP address value, throwing ConfigException if it is not valid
879 void ValidateIP(const char* p, const std::string &tag, const std::string &val, bool wild);
881 /** Validates a value that should not contain spaces, throwing ConfigException of it is not valid
883 void ValidateNoSpaces(const char* p, const std::string &tag, const std::string &val);
885 /** Returns the fully qualified path to the inspircd directory
886 * @return The full program directory
888 std::string GetFullProgDir();
890 /** Returns true if a directory is valid (within the modules directory).
891 * @param dirandfile The directory and filename to check
892 * @return True if the directory is valid
894 static bool DirValid(const char* dirandfile);
896 /** Clean a filename, stripping the directories (and drives) from string.
897 * @param name Directory to tidy
898 * @return The cleaned filename
900 static char* CleanFilename(char* name);
902 /** Check if a file exists.
903 * @param file The full path to a file
904 * @return True if the file exists and is readable.
906 static bool FileExists(const char* file);
908 /** If this value is true, invites will bypass more than just +i
914 /** Initialize the disabled commands list
916 CoreExport bool InitializeDisabledCommands(const char* data, InspIRCd* ServerInstance);
918 /** Initialize the oper types
920 bool InitTypes(ServerConfig* conf, const char* tag);
922 /** Initialize the oper classes
924 bool InitClasses(ServerConfig* conf, const char* tag);
926 /** Initialize an oper type
928 bool DoType(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
930 /** Initialize an oper class
932 bool DoClass(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
934 /** Finish initializing the oper types and classes
936 bool DoneClassesAndTypes(ServerConfig* conf, const char* tag);
940 /** Initialize x line
942 bool InitXLine(ServerConfig* conf, const char* tag);
944 /** Add a config-defined zline
946 bool DoZLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
948 /** Add a config-defined qline
950 bool DoQLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
952 /** Add a config-defined kline
954 bool DoKLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
956 /** Add a config-defined eline
958 bool DoELine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);