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