summaryrefslogtreecommitdiff
path: root/include/config.h
blob: 0a0a3103d04221b5ab418da8ca84cbb648e81f95 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
 *
 * (C) 2003-2024 Anope Team
 * Contact us at team@anope.org
 *
 * Please read COPYING and README for further details.
 *
 * Based on the original code of Epona by Lara.
 * Based on the original code of Services by Andy Church.
 */

#pragma once

#include "account.h"
#include "regchannel.h"
#include "users.h"
#include "opertype.h"

namespace Configuration
{
	namespace Internal
	{
	class CoreExport Block
	{
		friend struct Configuration::Conf;

	public:
		typedef Anope::map<Anope::string> item_map;
		typedef Anope::multimap<Block> block_map;

	private:
		Anope::string name;
		item_map items;
		block_map blocks;
		int linenum;

		/* Represents a missing tag. */
		static Block EmptyBlock;

	public:
		Block(const Anope::string &);
		const Anope::string &GetName() const;
		int CountBlock(const Anope::string &name) const;
		const Block *GetBlock(const Anope::string &name, int num = 0) const;
		Block *GetMutableBlock(const Anope::string &name, int num = 0);

		template<typename T> T Get(const Anope::string &tag, const Anope::string &def = "") const
		{
			return Anope::TryConvert<T>(this->Get<const Anope::string>(tag, def)).value_or(T());
		}

		bool Set(const Anope::string &tag, const Anope::string &value);
		const item_map &GetItems() const;
	};

	template<> CoreExport const Anope::string Block::Get(const Anope::string &tag, const Anope::string &def) const;
	template<> CoreExport time_t Block::Get(const Anope::string &tag, const Anope::string &def) const;
	template<> CoreExport bool Block::Get(const Anope::string &tag, const Anope::string &def) const;
	} // namespace Internal

	typedef const Internal::Block Block;
	typedef Internal::Block MutableBlock;

	/** Represents a configuration file
	 */
	class File final
	{
		Anope::string name;
		bool executable;
		FILE *fp = nullptr;
	public:
		File(const Anope::string &, bool);
		~File();
		const Anope::string &GetName() const;
		Anope::string GetPath() const;

		bool IsOpen() const;
		bool Open();
		void Close();
		bool End() const;
		Anope::string Read();
	};

	struct Uplink;

	struct CoreExport Conf final
		: Block
	{
		/* options:readtimeout */
		time_t ReadTimeout;
		/* If we should default to privmsging clients */
		bool DefPrivmsg;
		/* Default language */
		Anope::string DefLanguage;
		/* options:timeoutcheck */
		time_t TimeoutCheck;
		/* options:servicealias */
		bool ServiceAlias;
		/* networkinfo:nickchars */
		Anope::string NickChars;

		/* List of uplink servers to try and connect to */
		std::vector<Uplink> Uplinks;
		/* A vector of our logfile options */
		std::vector<LogInfo> LogInfos;
		/* Array of ulined servers */
		std::vector<Anope::string> Ulines;
		/* List of available opertypes */
		std::vector<OperType *> MyOperTypes;
		/* List of pairs of opers and their opertype from the config */
		std::vector<Oper *> Opers;
		/* Map of fantasy commands */
		CommandInfo::map Fantasy;
		/* Command groups */
		std::vector<CommandGroup> CommandGroups;
		/* List of modules to autoload */
		std::vector<Anope::string> ModulesAutoLoad;

		/* module configuration blocks */
		std::map<Anope::string, Block *> modules;
		Anope::map<Anope::string> bots;

		Conf();
		~Conf();

		void LoadConf(File &file);
		void Post(Conf *old);

		Block *GetModule(Module *);
		Block *GetModule(const Anope::string &name);

		BotInfo *GetClient(const Anope::string &name);

		const Block *GetCommand(CommandSource &);
	};

	struct Uplink final
	{
		Anope::string host;
		unsigned port;
		Anope::string password;
		int protocol;

		Uplink(const Anope::string &_host, int _port, const Anope::string &_password, int _protocol) : host(_host), port(_port), password(_password), protocol(_protocol) { }
		inline bool operator==(const Uplink &other) const { return host == other.host && port == other.port && password == other.password && protocol == other.protocol; }
		inline bool operator!=(const Uplink &other) const { return !(*this == other); }
	};
}

/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception.
 * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or
 * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not
 * be loaded. If this happens, the error message returned by ModuleException::GetReason will be displayed to the user
 * attempting to load the module, or dumped to the console if the ircd is currently loading for the first time.
 */
class CoreExport ConfigException final
	: public CoreException
{
public:
	/** Default constructor, just uses the error message 'Config threw an exception'.
	 */
	ConfigException() : CoreException("Config threw an exception", "Config Parser") { }
	/** This constructor can be used to specify an error message before throwing.
	 */
	ConfigException(const Anope::string &message) : CoreException(message, "Config Parser") { }
	/** This destructor solves world hunger, cancels the world debt, and causes the world to end.
	 * Actually no, it does nothing. Never mind.
	 * @throws Nothing!
	 */
	virtual ~ConfigException() noexcept = default;
};

extern Configuration::File ServicesConf;
extern CoreExport Configuration::Conf *Config;