]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/configreader.h
3c8a58e64e57c3968fa88edb179598c291cf4230
[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         ValueContainerBase* val;
143         ConfigDataType datatype;
144         Validator validation_function;
145 };
146
147 /** Holds a core configuration item and its callbacks
148  * where there may be more than one item
149  */
150 struct MultiConfig
151 {
152         const char*     tag;
153         char*           items[12];
154         int             datatype[12];
155         MultiNotify     init_function;
156         MultiValidator  validation_function;
157         MultiNotify     finish_function;
158 };
159
160 /** A set of oper types
161  */
162 typedef std::map<irc::string,char*> opertype_t;
163
164 /** A Set of oper classes
165  */
166 typedef std::map<irc::string,char*> operclass_t;
167
168
169 /** This class holds the bulk of the runtime configuration for the ircd.
170  * It allows for reading new config values, accessing configuration files,
171  * and storage of the configuration data needed to run the ircd, such as
172  * the servername, connect classes, /ADMIN data, MOTDs and filenames etc.
173  */
174 class ServerConfig : public Extensible
175 {
176   private:
177         /** Creator/owner
178          */
179         InspIRCd* ServerInstance;
180
181         /** This variable holds the names of all
182          * files included from the main one. This
183          * is used to make sure that no files are
184          * recursively included.
185          */
186         std::vector<std::string> include_stack;
187
188         /** This private method processes one line of
189          * configutation, appending errors to errorstream
190          * and setting error if an error has occured.
191          */
192         bool ParseLine(ConfigDataHash &target, std::string &line, long linenumber, std::ostringstream &errorstream);
193   
194         /** Process an include directive
195          */
196         bool DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream);
197
198         /** Check that there is only one of each configuration item
199          */
200         bool CheckOnce(char* tag, bool bail, userrec* user);
201   
202   public:
203
204         InspIRCd* GetInstance();
205           
206         /** This holds all the information in the config file,
207          * it's indexed by tag name to a vector of key/values.
208          */
209         ConfigDataHash config_data;
210
211         /** Max number of WhoWas entries per user.
212          */
213         int WhoWasGroupSize;
214
215         /** Max number of cumulative user-entries in WhoWas.
216          *  When max reached and added to, push out oldest entry FIFO style.
217          */
218         int WhoWasMaxGroups;
219
220         /** Max seconds a user is kept in WhoWas before being pruned.
221          */
222         int WhoWasMaxKeep;
223
224         /** Holds the server name of the local server
225          * as defined by the administrator.
226          */
227         char ServerName[MAXBUF];
228         
229         /* Holds the network name the local server
230          * belongs to. This is an arbitary field defined
231          * by the administrator.
232          */
233         char Network[MAXBUF];
234
235         /** Holds the description of the local server
236          * as defined by the administrator.
237          */
238         char ServerDesc[MAXBUF];
239
240         /** Holds the admin's name, for output in
241          * the /ADMIN command.
242          */
243         char AdminName[MAXBUF];
244
245         /** Holds the email address of the admin,
246          * for output in the /ADMIN command.
247          */
248         char AdminEmail[MAXBUF];
249
250         /** Holds the admin's nickname, for output
251          * in the /ADMIN command
252          */
253         char AdminNick[MAXBUF];
254
255         /** The admin-configured /DIE password
256          */
257         char diepass[MAXBUF];
258
259         /** The admin-configured /RESTART password
260          */
261         char restartpass[MAXBUF];
262
263         /** The pathname and filename of the message of the
264          * day file, as defined by the administrator.
265          */
266         char motd[MAXBUF];
267
268         /** The pathname and filename of the rules file,
269          * as defined by the administrator.
270          */
271         char rules[MAXBUF];
272
273         /** The quit prefix in use, or an empty string
274          */
275         char PrefixQuit[MAXBUF];
276
277         /** The last string found within a <die> tag, or
278          * an empty string.
279          */
280         char DieValue[MAXBUF];
281
282         /** The DNS server to use for DNS queries
283          */
284         char DNSServer[MAXBUF];
285
286         /** This variable contains a space-seperated list
287          * of commands which are disabled by the
288          * administrator of the server for non-opers.
289          */
290         char DisabledCommands[MAXBUF];
291
292         /** The full path to the modules directory.
293          * This is either set at compile time, or
294          * overridden in the configuration file via
295          * the <options> tag.
296          */
297         char ModPath[1024];
298
299         /** The full pathname to the executable, as
300          * given in argv[0] when the program starts.
301          */
302         char MyExecutable[1024];
303
304         /** The file handle of the logfile. If this
305          * value is NULL, the log file is not open,
306          * probably due to a permissions error on
307          * startup (this should not happen in normal
308          * operation!).
309          */
310         FILE *log_file;
311
312         /** If this value is true, the owner of the
313          * server specified -nofork on the command
314          * line, causing the daemon to stay in the
315          * foreground.
316          */
317         bool nofork;
318         
319         /** If this value if true then all log
320          * messages will be output, regardless of
321          * the level given in the config file.
322          * This is set with the -debug commandline
323          * option.
324          */
325         bool forcedebug;
326         
327         /** If this is true then log output will be
328          * written to the logfile. This is the default.
329          * If you put -nolog on the commandline then
330          * the logfile will not be written.
331          * This is meant to be used in conjunction with
332          * -debug for debugging without filling up the
333          * hard disk.
334          */
335         bool writelog;
336
337         /** If this value is true, halfops have been
338          * enabled in the configuration file.
339          */
340         bool AllowHalfop;
341
342         /** The number of seconds the DNS subsystem
343          * will wait before timing out any request.
344          */
345         int dns_timeout;
346
347         /** The size of the read() buffer in the user
348          * handling code, used to read data into a user's
349          * recvQ.
350          */
351         int NetBufferSize;
352
353         /** The value to be used for listen() backlogs
354          * as default.
355          */
356         int MaxConn;
357
358         /** The soft limit value assigned to the irc server.
359          * The IRC server will not allow more than this
360          * number of local users.
361          */
362         unsigned int SoftLimit;
363
364         /** Maximum number of targets for a multi target command
365          * such as PRIVMSG or KICK
366          */
367         unsigned int MaxTargets;
368
369         /** The maximum number of /WHO results allowed
370          * in any single /WHO command.
371          */
372         int MaxWhoResults;
373
374         /** True if the DEBUG loglevel is selected.
375          */
376         int debugging;
377
378         /** The loglevel in use by the IRC server
379          */
380         int LogLevel;
381
382         /** How many seconds to wait before exiting
383          * the program when /DIE is correctly issued.
384          */
385         int DieDelay;
386
387         /** True if we're going to hide netsplits as *.net *.split for non-opers
388          */
389         bool HideSplits;
390
391         /** True if we're going to hide ban reasons for non-opers (e.g. G-Lines,
392          * K-Lines, Z-Lines)
393          */
394         bool HideBans;
395
396         /** If this is enabled then operators will
397          * see invisible (+i) channels in /whois.
398          */
399         bool OperSpyWhois;
400
401         /** Set to a non-empty string to obfuscate the server name of users in WHOIS
402          */
403         char HideWhoisServer[MAXBUF];
404
405         /** A list of IP addresses the server is listening
406          * on.
407          */
408         char addrs[MAXBUF][255];
409
410         /** The MOTD file, cached in a file_cache type.
411          */
412         file_cache MOTD;
413
414         /** The RULES file, cached in a file_cache type.
415          */
416         file_cache RULES;
417
418         /** The full pathname and filename of the PID
419          * file as defined in the configuration.
420          */
421         char PID[1024];
422
423         /** The connect classes in use by the IRC server.
424          */
425         ClassVector Classes;
426
427         /** A list of module names (names only, no paths)
428          * which are currently loaded by the server.
429          */
430         std::vector<std::string> module_names;
431
432         /** A list of ports which the server is listening on
433          */
434         int ports[255];
435
436         /** A list of the file descriptors for the listening client ports
437          */
438         ListenSocket* openSockfd[255];
439
440         /** Boolean sets of which modules implement which functions
441          */
442         char implement_lists[255][255];
443
444         /** Global implementation list
445          */
446         char global_implementation[255];
447
448         /** A list of ports claimed by IO Modules
449          */
450         std::map<int,Module*> IOHookModule;
451
452         std::map<InspSocket*, Module*> SocketIOHookModule;
453
454         /** The 005 tokens of this server (ISUPPORT)
455          * populated/repopulated upon loading or unloading
456          * modules.
457          */
458         std::string data005;
459         std::vector<std::string> isupport;
460
461         /** STATS characters in this list are available
462          * only to operators.
463          */
464         char UserStats[MAXBUF];
465         
466         /** The path and filename of the ircd.log file
467          */
468         std::string logpath;
469
470         /** Custom version string, which if defined can replace the system info in VERSION.
471          */
472         char CustomVersion[MAXBUF];
473
474         /** List of u-lined servers
475          */
476         std::vector<irc::string> ulines;
477
478         /** Max banlist sizes for channels (the std::string is a glob)
479          */
480         std::map<std::string,int> maxbans;
481
482         /** Directory where the inspircd binary resides
483          */
484         std::string MyDir;
485
486         /** If set to true, no user DNS lookups are to be performed
487          */
488         bool NoUserDns;
489
490         /** If set to true, provide syntax hints for unknown commands
491          */
492         bool SyntaxHints;
493
494         /** If set to true, users appear to quit then rejoin when their hosts change.
495          * This keeps clients synchronized properly.
496          */
497         bool CycleHosts;
498
499         /** If set to true, prefixed channel NOTICEs and PRIVMSGs will have the prefix
500          *  added to the outgoing text for undernet style msg prefixing.
501          */
502         bool UndernetMsgPrefix;
503
504         /** All oper type definitions from the config file
505          */
506         opertype_t opertypes;
507
508         /** All oper class definitions from the config file
509          */
510         operclass_t operclass;
511
512         /** Saved argv from startup
513          */
514         char** argv;
515
516         /** Saved argc from startup
517          */
518         int argc;
519
520         /** Construct a new ServerConfig
521          */
522         ServerConfig(InspIRCd* Instance);
523
524         /** Clears the include stack in preperation for a Read() call.
525          */
526         void ClearStack();
527
528         /** Update the 005 vector
529          */
530         void Update005();
531
532         /** Send the 005 numerics (ISUPPORT) to a user
533          */
534         void Send005(userrec* user);
535
536         /** Read the entire configuration into memory
537          * and initialize this class. All other methods
538          * should be used only by the core.
539          */
540         void Read(bool bail, userrec* user);
541
542         /** Read a file into a file_cache object
543          */
544         bool ReadFile(file_cache &F, const char* fname);
545
546         /** Load 'filename' into 'target', with the new config parser everything is parsed into
547          * tag/key/value at load-time rather than at read-value time.
548          */
549
550         /** Report a configuration error given in errormessage.
551          * @param bail If this is set to true, the error is sent to the console, and the program exits
552          * @param user If this is set to a non-null value, and bail is false, the errors are spooled to
553          * this user as SNOTICEs.
554          * If the parameter is NULL, the messages are spooled to all users via WriteOpers as SNOTICEs.
555          */
556         void ReportConfigError(const std::string &errormessage, bool bail, userrec* user);
557
558         /** Load 'filename' into 'target', with the new config parser everything is parsed into
559          * tag/key/value at load-time rather than at read-value time.
560          */
561         bool LoadConf(ConfigDataHash &target, const char* filename, std::ostringstream &errorstream);
562
563         /** Load 'filename' into 'target', with the new config parser everything is parsed into
564          * tag/key/value at load-time rather than at read-value time.
565          */
566         bool LoadConf(ConfigDataHash &target, const std::string &filename, std::ostringstream &errorstream);
567         
568         /* Both these return true if the value existed or false otherwise */
569         
570         /** Writes 'length' chars into 'result' as a string
571          */
572         bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds = false);
573         /** Writes 'length' chars into 'result' as a string
574          */
575         bool ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, std::string &result, bool allow_linefeeds = false);
576         
577         /** Tries to convert the value to an integer and write it to 'result'
578          */
579         bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, int index, int &result);
580         /** Tries to convert the value to an integer and write it to 'result'
581          */
582         bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, int &result);
583         
584         /** Returns true if the value exists and has a true value, false otherwise
585          */
586         bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, int index);
587         /** Returns true if the value exists and has a true value, false otherwise
588          */
589         bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, int index);
590         
591         /** Returns the number of occurences of tag in the config file
592          */
593         int ConfValueEnum(ConfigDataHash &target, const char* tag);
594         /** Returns the number of occurences of tag in the config file
595          */
596         int ConfValueEnum(ConfigDataHash &target, const std::string &tag);
597         
598         /** Returns the numbers of vars inside the index'th 'tag in the config file
599          */
600         int ConfVarEnum(ConfigDataHash &target, const char* tag, int index);
601         /** Returns the numbers of vars inside the index'th 'tag in the config file
602          */
603         int ConfVarEnum(ConfigDataHash &target, const std::string &tag, int index);
604         
605         Module* GetIOHook(int port);
606         bool AddIOHook(int port, Module* iomod);
607         bool DelIOHook(int port);
608         Module* GetIOHook(InspSocket* is);
609         bool AddIOHook(Module* iomod, InspSocket* is);
610         bool DelIOHook(InspSocket* is);
611
612         static std::string GetFullProgDir(char** argv, int argc);
613         static bool DirValid(const char* dirandfile);
614         static char* CleanFilename(char* name);
615         static bool FileExists(const char* file);
616         
617 };
618
619 bool InitializeDisabledCommands(const char* data, InspIRCd* ServerInstance);
620
621 bool InitTypes(ServerConfig* conf, const char* tag);
622 bool InitClasses(ServerConfig* conf, const char* tag);
623 bool DoType(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
624 bool DoClass(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types);
625 bool DoneClassesAndTypes(ServerConfig* conf, const char* tag);
626
627 #endif