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