]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/configreader.h
4d5435b1ca43de55f5a4314c34083d0301678849
[user/henk/code/inspircd.git] / include / configreader.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #ifndef INSPIRCD_CONFIGREADER
15 #define INSPIRCD_CONFIGREADER
16
17 /* handy defines */
18
19 /** Determines if a channel op is exempt from given mode m,
20  * in config of server instance s. 
21  */
22 #define CHANOPS_EXEMPT(s, m) (s->Config->ExemptChanOps[(unsigned char)m])
23
24 #include <sstream>
25 #include <string>
26 #include <vector>
27 #include <map>
28 #include "inspircd.h"
29 #include "globals.h"
30 #include "modules.h"
31 #include "socketengine.h"
32 #include "socket.h"
33
34 class ServerConfig;
35 class InspIRCd;
36 class InspSocket;
37
38 /** Types of data in the core config
39  */
40 enum ConfigDataType
41 {
42         DT_NOTHING       = 0,
43         DT_INTEGER       = 1,
44         DT_CHARPTR       = 2,
45         DT_BOOLEAN       = 3,
46         DT_ALLOW_NEWLINE = 128
47 };
48
49 /** Holds a config value, either string, integer or boolean.
50  * Callback functions receive one or more of these, either on
51  * their own as a reference, or in a reference to a deque of them.
52  * The callback function can then alter the values of the ValueItem
53  * classes to validate the settings.
54  */
55 class ValueItem
56 {
57         std::string v;
58  public:
59         ValueItem(int value);
60         ValueItem(bool value);
61         ValueItem(char* value);
62         void Set(char* value);
63         void Set(const char* val);
64         void Set(int value);
65         int GetInteger();
66         char* GetString();
67         bool GetBool();
68 };
69
70 /** The base class of the container 'ValueContainer'
71  * used internally by the core to hold core values.
72  */
73 class ValueContainerBase
74 {
75  public:
76         ValueContainerBase() { }
77         virtual ~ValueContainerBase() { }
78 };
79
80 /** ValueContainer is used to contain pointers to different
81  * core values such as the server name, maximum number of
82  * clients etc.
83  * It is specialized to hold a data type, then pointed at
84  * a value in the ServerConfig class. When the value has been
85  * read and validated, the Set method is called to write the
86  * value safely in a type-safe manner.
87  */
88 template<typename T> class ValueContainer : public ValueContainerBase
89 {
90         T val;
91
92  public:
93
94         ValueContainer()
95         {
96                 val = NULL;
97         }
98
99         ValueContainer(T Val)
100         {
101                 val = Val;
102         }
103
104         void Set(T newval, size_t s)
105         {
106                 memcpy(val, newval, s);
107         }
108 };
109
110 /** A specialization of ValueContainer to hold a pointer to a bool
111  */
112 typedef ValueContainer<bool*> ValueContainerBool;
113
114 /** A specialization of ValueContainer to hold a pointer to
115  * an unsigned int
116  */
117 typedef ValueContainer<unsigned int*> ValueContainerUInt;
118
119 /** A specialization of ValueContainer to hold a pointer to
120  * a char array.
121  */
122 typedef ValueContainer<char*> ValueContainerChar;
123
124 /** A specialization of ValueContainer to hold a pointer to
125  * an int
126  */
127 typedef ValueContainer<int*> ValueContainerInt;
128
129 /** A set of ValueItems used by multi-value validator functions
130  */
131 typedef std::deque<ValueItem> ValueList;
132
133 /** A callback for validating a single value
134  */
135 typedef bool (*Validator)(ServerConfig* conf, const char*, const char*, ValueItem&);
136 /** A callback for validating multiple value entries
137  */
138 typedef bool (*MultiValidator)(ServerConfig* conf, const char*, char**, ValueList&, int*);
139 /** A callback indicating the end of a group of entries
140  */
141 typedef bool (*MultiNotify)(ServerConfig* conf, const char*);
142
143 /** Holds a core configuration item and its callbacks
144  */
145 struct InitialConfig
146 {
147         char* tag;
148         char* value;
149         char* default_value;
150         ValueContainerBase* val;
151         ConfigDataType datatype;
152         Validator validation_function;
153 };
154
155 /** Holds a core configuration item and its callbacks
156  * where there may be more than one item
157  */
158 struct MultiConfig
159 {
160         const char*     tag;
161         char*           items[13];
162         char*           items_default[13];
163         int             datatype[13];
164         MultiNotify     init_function;
165         MultiValidator  validation_function;
166         MultiNotify     finish_function;
167 };
168
169 /** A set of oper types
170  */
171 typedef std::map<irc::string,char*> opertype_t;
172
173 /** A Set of oper classes
174  */
175 typedef std::map<irc::string,char*> operclass_t;
176
177
178 /** This class holds the bulk of the runtime configuration for the ircd.
179  * It allows for reading new config values, accessing configuration files,
180  * and storage of the configuration data needed to run the ircd, such as
181  * the servername, connect classes, /ADMIN data, MOTDs and filenames etc.
182  */
183 class CoreExport ServerConfig : public Extensible
184 {
185   private:
186         /** Creator/owner
187          */
188         InspIRCd* ServerInstance;
189
190         /** This variable holds the names of all
191          * files included from the main one. This
192          * is used to make sure that no files are
193          * recursively included.
194          */
195         std::vector<std::string> include_stack;
196
197         /** This private method processes one line of
198          * configutation, appending errors to errorstream
199          * and setting error if an error has occured.
200          */
201         bool ParseLine(ConfigDataHash &target, std::string &line, long linenumber, std::ostringstream &errorstream);
202   
203         /** Process an include directive
204          */
205         bool DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream);
206
207         /** Check that there is only one of each configuration item
208          */
209         bool CheckOnce(char* tag, bool bail, userrec* user);
210   
211   public:
212
213         InspIRCd* GetInstance();
214           
215         /** This holds all the information in the config file,
216          * it's indexed by tag name to a vector of key/values.
217          */
218         ConfigDataHash config_data;
219
220         /** Max number of WhoWas entries per user.
221          */
222         int WhoWasGroupSize;
223
224         /** Max number of cumulative user-entries in WhoWas.
225          *  When max reached and added to, push out oldest entry FIFO style.
226          */
227         int WhoWasMaxGroups;
228
229         /** Max seconds a user is kept in WhoWas before being pruned.
230          */
231         int WhoWasMaxKeep;
232
233         /** Holds the server name of the local server
234          * as defined by the administrator.
235          */
236         char ServerName[MAXBUF];
237
238         /** Notice to give to users when they are Xlined
239          */
240         char MoronBanner[MAXBUF];
241         
242         /* Holds the network name the local server
243          * belongs to. This is an arbitary field defined
244          * by the administrator.
245          */
246         char Network[MAXBUF];
247
248         /** Holds the description of the local server
249          * as defined by the administrator.
250          */
251         char ServerDesc[MAXBUF];
252
253         /** Holds the admin's name, for output in
254          * the /ADMIN command.
255          */
256         char AdminName[MAXBUF];
257
258         /** Holds the email address of the admin,
259          * for output in the /ADMIN command.
260          */
261         char AdminEmail[MAXBUF];
262
263         /** Holds the admin's nickname, for output
264          * in the /ADMIN command
265          */
266         char AdminNick[MAXBUF];
267
268         /** The admin-configured /DIE password
269          */
270         char diepass[MAXBUF];
271
272         /** The admin-configured /RESTART password
273          */
274         char restartpass[MAXBUF];
275
276         /** The pathname and filename of the message of the
277          * day file, as defined by the administrator.
278          */
279         char motd[MAXBUF];
280
281         /** The pathname and filename of the rules file,
282          * as defined by the administrator.
283          */
284         char rules[MAXBUF];
285
286         /** The quit prefix in use, or an empty string
287          */
288         char PrefixQuit[MAXBUF];
289
290         /** The quit suffix in use, or an empty string
291          */
292         char SuffixQuit[MAXBUF];
293
294         /** The fixed quit message in use, or an empty string
295          */
296         char FixedQuit[MAXBUF];
297
298         /** The last string found within a <die> tag, or
299          * an empty string.
300          */
301         char DieValue[MAXBUF];
302
303         /** The DNS server to use for DNS queries
304          */
305         char DNSServer[MAXBUF];
306
307         /** This variable contains a space-seperated list
308          * of commands which are disabled by the
309          * administrator of the server for non-opers.
310          */
311         char DisabledCommands[MAXBUF];
312
313         /** The full path to the modules directory.
314          * This is either set at compile time, or
315          * overridden in the configuration file via
316          * the <options> tag.
317          */
318         char ModPath[1024];
319
320         /** The full pathname to the executable, as
321          * given in argv[0] when the program starts.
322          */
323         char MyExecutable[1024];
324
325         /** The file handle of the logfile. If this
326          * value is NULL, the log file is not open,
327          * probably due to a permissions error on
328          * startup (this should not happen in normal
329          * operation!).
330          */
331         FILE *log_file;
332
333         /** If this value is true, the owner of the
334          * server specified -nofork on the command
335          * line, causing the daemon to stay in the
336          * foreground.
337          */
338         bool nofork;
339         
340         /** If this value if true then all log
341          * messages will be output, regardless of
342          * the level given in the config file.
343          * This is set with the -debug commandline
344          * option.
345          */
346         bool forcedebug;
347         
348         /** If this is true then log output will be
349          * written to the logfile. This is the default.
350          * If you put -nolog on the commandline then
351          * the logfile will not be written.
352          * This is meant to be used in conjunction with
353          * -debug for debugging without filling up the
354          * hard disk.
355          */
356         bool writelog;
357
358         /** If this value is true, halfops have been
359          * enabled in the configuration file.
360          */
361         bool AllowHalfop;
362
363         /** If this is set to true, then mode lists (e.g
364          * MODE #chan b) are hidden from unprivileged
365          * users.
366          */
367         bool HideModeLists[256];
368
369         /** If this is set to true, then channel operators
370          * are exempt from this channel mode. Used for +Sc etc.
371          */
372         bool ExemptChanOps[256];
373
374         /** The number of seconds the DNS subsystem
375          * will wait before timing out any request.
376          */
377         int dns_timeout;
378
379         /** The size of the read() buffer in the user
380          * handling code, used to read data into a user's
381          * recvQ.
382          */
383         int NetBufferSize;
384
385         /** The value to be used for listen() backlogs
386          * as default.
387          */
388         int MaxConn;
389
390         /** The soft limit value assigned to the irc server.
391          * The IRC server will not allow more than this
392          * number of local users.
393          */
394         unsigned int SoftLimit;
395
396         /** Maximum number of targets for a multi target command
397          * such as PRIVMSG or KICK
398          */
399         unsigned int MaxTargets;
400
401         /** The maximum number of /WHO results allowed
402          * in any single /WHO command.
403          */
404         int MaxWhoResults;
405
406         /** True if the DEBUG loglevel is selected.
407          */
408         int debugging;
409
410         /** The loglevel in use by the IRC server
411          */
412         int LogLevel;
413
414         /** How many seconds to wait before exiting
415          * the program when /DIE is correctly issued.
416          */
417         int DieDelay;
418
419         /** True if we're going to hide netsplits as *.net *.split for non-opers
420          */
421         bool HideSplits;
422
423         /** True if we're going to hide ban reasons for non-opers (e.g. G-Lines,
424          * K-Lines, Z-Lines)
425          */
426         bool HideBans;
427
428         /** Announce invites to the channel with a server notice
429          */
430         bool AnnounceInvites;
431
432         /** If this is enabled then operators will
433          * see invisible (+i) channels in /whois.
434          */
435         bool OperSpyWhois;
436
437         /** Set to a non-empty string to obfuscate the server name of users in WHOIS
438          */
439         char HideWhoisServer[MAXBUF];
440
441         /** Set to a non empty string to obfuscate nicknames prepended to a KILL.
442          */
443         char HideKillsServer[MAXBUF];
444
445         /** The MOTD file, cached in a file_cache type.
446          */
447         file_cache MOTD;
448
449         /** The RULES file, cached in a file_cache type.
450          */
451         file_cache RULES;
452
453         /** The full pathname and filename of the PID
454          * file as defined in the configuration.
455          */
456         char PID[1024];
457
458         /** The connect classes in use by the IRC server.
459          */
460         ClassVector Classes;
461
462         /** A list of module names (names only, no paths)
463          * which are currently loaded by the server.
464          */
465         std::vector<std::string> module_names;
466
467         /** A list of the classes for listening client ports
468          */
469         std::vector<ListenSocket*> ports;
470
471         /** Boolean sets of which modules implement which functions
472          */
473         char implement_lists[255][255];
474
475         /** Global implementation list
476          */
477         char global_implementation[255];
478
479         /** A list of ports claimed by IO Modules
480          */
481         std::map<int,Module*> IOHookModule;
482
483         std::map<InspSocket*, Module*> SocketIOHookModule;
484
485         /** The 005 tokens of this server (ISUPPORT)
486          * populated/repopulated upon loading or unloading
487          * modules.
488          */
489         std::string data005;
490         std::vector<std::string> isupport;
491
492         /** STATS characters in this list are available
493          * only to operators.
494          */
495         char UserStats[MAXBUF];
496         
497         /** The path and filename of the ircd.log file
498          */
499         std::string logpath;
500
501         /** Default channel modes
502          */
503         char DefaultModes[MAXBUF];
504
505         /** Custom version string, which if defined can replace the system info in VERSION.
506          */
507         char CustomVersion[MAXBUF];
508
509         /** List of u-lined servers
510          */
511         std::map<irc::string, bool> ulines;
512
513         /** Max banlist sizes for channels (the std::string is a glob)
514          */
515         std::map<std::string, int> maxbans;
516
517         /** Directory where the inspircd binary resides
518          */
519         std::string MyDir;
520
521         /** If set to true, no user DNS lookups are to be performed
522          */
523         bool NoUserDns;
524
525         /** If set to true, provide syntax hints for unknown commands
526          */
527         bool SyntaxHints;
528
529         /** If set to true, users appear to quit then rejoin when their hosts change.
530          * This keeps clients synchronized properly.
531          */
532         bool CycleHosts;
533
534         /** If set to true, prefixed channel NOTICEs and PRIVMSGs will have the prefix
535          *  added to the outgoing text for undernet style msg prefixing.
536          */
537         bool UndernetMsgPrefix;
538
539         /** If set to true, the full nick!user@host will be shown in the TOPIC command
540          * for who set the topic last. If false, only the nick is shown.
541          */
542         bool FullHostInTopic;
543
544         /** All oper type definitions from the config file
545          */
546         opertype_t opertypes;
547
548         /** All oper class definitions from the config file
549          */
550         operclass_t operclass;
551
552         /** Saved argv from startup
553          */
554         char** argv;
555
556         /** Saved argc from startup
557          */
558         int argc;
559
560         /** Max channels per user
561          */
562         unsigned int MaxChans;
563
564         /** Oper max channels per user
565          */
566         unsigned int OperMaxChans;
567
568         /** Construct a new ServerConfig
569          */
570         ServerConfig(InspIRCd* Instance);
571
572         /** Clears the include stack in preperation for a Read() call.
573          */
574         void ClearStack();
575
576         /** Update the 005 vector
577          */
578         void Update005();
579
580         /** Send the 005 numerics (ISUPPORT) to a user
581          */
582         void Send005(userrec* user);
583
584         /** Read the entire configuration into memory
585          * and initialize this class. All other methods
586          * should be used only by the core.
587          */
588         void Read(bool bail, userrec* user);
589
590         /** Read a file into a file_cache object
591          */
592         bool ReadFile(file_cache &F, const char* fname);
593
594         /** Load 'filename' into 'target', with the new config parser everything is parsed into
595          * tag/key/value at load-time rather than at read-value time.
596          */
597
598         /** Report a configuration error given in errormessage.
599          * @param bail If this is set to true, the error is sent to the console, and the program exits
600          * @param user If this is set to a non-null value, and bail is false, the errors are spooled to
601          * this user as SNOTICEs.
602          * If the parameter is NULL, the messages are spooled to all users via WriteOpers as SNOTICEs.
603          */
604         void ReportConfigError(const std::string &errormessage, bool bail, userrec* user);
605
606         /** Load 'filename' into 'target', with the new config parser everything is parsed into
607          * tag/key/value at load-time rather than at read-value time.
608          */
609         bool LoadConf(ConfigDataHash &target, const char* filename, std::ostringstream &errorstream);
610
611         /** Load 'filename' into 'target', with the new config parser everything is parsed into
612          * tag/key/value at load-time rather than at read-value time.
613          */
614         bool LoadConf(ConfigDataHash &target, const std::string &filename, std::ostringstream &errorstream);
615         
616         /* Both these return true if the value existed or false otherwise */
617         
618         /** Writes 'length' chars into 'result' as a string
619          */
620         bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds = false);
621         bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, char* result, int length, bool allow_linefeeds = false);
622
623         /** Writes 'length' chars into 'result' as a string
624          */
625         bool ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, std::string &result, bool allow_linefeeds = false);
626         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);
627         
628         /** Tries to convert the value to an integer and write it to 'result'
629          */
630         bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, int index, int &result);
631         bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, int &result);
632         /** Tries to convert the value to an integer and write it to 'result'
633          */
634         bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, int &result);
635         bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, int &result);
636         
637         /** Returns true if the value exists and has a true value, false otherwise
638          */
639         bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, int index);
640         bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index);
641         /** Returns true if the value exists and has a true value, false otherwise
642          */
643         bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, int index);
644         bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index);
645         
646         /** Returns the number of occurences of tag in the config file
647          */
648         int ConfValueEnum(ConfigDataHash &target, const char* tag);
649         /** Returns the number of occurences of tag in the config file
650          */
651         int ConfValueEnum(ConfigDataHash &target, const std::string &tag);
652         
653         /** Returns the numbers of vars inside the index'th 'tag in the config file
654          */
655         int ConfVarEnum(ConfigDataHash &target, const char* tag, int index);
656         /** Returns the numbers of vars inside the index'th 'tag in the config file
657          */
658         int ConfVarEnum(ConfigDataHash &target, const std::string &tag, int index);
659         
660         Module* GetIOHook(int port);
661         bool AddIOHook(int port, Module* iomod);
662         bool DelIOHook(int port);
663         Module* GetIOHook(InspSocket* is);
664         bool AddIOHook(Module* iomod, InspSocket* is);
665         bool DelIOHook(InspSocket* is);
666
667         std::string GetFullProgDir();
668         static bool DirValid(const char* dirandfile);
669         static char* CleanFilename(char* name);
670         static bool FileExists(const char* file);
671         
672 };
673
674 CoreExport bool InitializeDisabledCommands(const char* data, InspIRCd* ServerInstance);
675
676 bool InitTypes(ServerConfig* conf, const char* tag);
677 bool InitClasses(ServerConfig* conf, const char* tag);
678 bool DoType(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
679 bool DoClass(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
680 bool DoneClassesAndTypes(ServerConfig* conf, const char* tag);
681
682 #endif