mirror of
https://github.com/matrix-construct/construct
synced 2024-11-25 16:22:35 +01:00
Introduce modular configuration system.
This commit is contained in:
parent
d2bb8cd8a7
commit
2742547826
8 changed files with 664 additions and 100 deletions
|
@ -28,32 +28,131 @@ namespace ircd {
|
|||
namespace conf {
|
||||
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
IRCD_EXCEPTION(error, already_exists)
|
||||
IRCD_EXCEPTION(error, bad_topconf)
|
||||
IRCD_EXCEPTION(error, not_found)
|
||||
IRCD_EXCEPTION(error, bad_cast)
|
||||
|
||||
extern struct log::log log;
|
||||
struct item
|
||||
{
|
||||
uint8_t *ptr;
|
||||
std::type_index type;
|
||||
|
||||
template<class T> item(T *ptr);
|
||||
};
|
||||
|
||||
struct top
|
||||
:cmd
|
||||
{
|
||||
using items = std::initializer_list<std::pair<std::string, item>>;
|
||||
|
||||
char letter;
|
||||
std::string name;
|
||||
std::unordered_map<std::string, item> map;
|
||||
|
||||
// Override to provide custom type handling
|
||||
virtual void assign(item &item, std::string val) const;
|
||||
|
||||
// Override to provide operations on singleton blocks
|
||||
virtual const uint8_t *get(client::client &, const std::string &key) const;
|
||||
virtual void set(client::client &, std::string key, std::string val);
|
||||
virtual void del(client::client &, const std::string &key);
|
||||
virtual void enu(client::client &, const std::string &key);
|
||||
|
||||
// Override to provide operations on named blocks
|
||||
virtual const uint8_t *get(client::client &, const std::string &label, const std::string &key) const;
|
||||
virtual void set(client::client &, std::string label, std::string key, std::string val);
|
||||
virtual void del(client::client &, const std::string &label, const std::string &key);
|
||||
virtual void enu(client::client &, const std::string &label, const std::string &key);
|
||||
|
||||
// Override to handle the raw line
|
||||
virtual void operator()(client::client &, line) override;
|
||||
|
||||
top(const char &letter, const std::string &name, const items & = {});
|
||||
~top() noexcept;
|
||||
};
|
||||
|
||||
namespace newconf
|
||||
{
|
||||
IRCD_EXCEPTION(conf::error, error)
|
||||
IRCD_EXCEPTION(error, unknown_block)
|
||||
|
||||
using letters = std::array<std::string, 256>;
|
||||
|
||||
extern topconf current; // The latest newconf parse map after startup or rehash
|
||||
extern topconf last; // The current is moved to last for differentiation
|
||||
extern letters registry; // Translates newconf block names into characters
|
||||
|
||||
uint8_t find_letter(const std::string &name);
|
||||
std::forward_list<std::string> translate(const topconf &);
|
||||
}
|
||||
|
||||
extern struct log::log log;
|
||||
extern std::array<top *, 256> confs;
|
||||
|
||||
// Dynamic casting closure
|
||||
using type_handler = std::function<void (uint8_t *const &ptr, std::string text)>;
|
||||
extern std::map<std::type_index, type_handler> type_handlers;
|
||||
|
||||
template<class T> std::type_index make_index();
|
||||
template<class T = std::string> const T &get(client::client &, const char &, const std::string &label, const std::string &key);
|
||||
template<class T = std::string> const T &get(client::client &, const char &, const std::string &key);
|
||||
|
||||
void init(const std::string &path);
|
||||
|
||||
|
||||
template<class T>
|
||||
const T &
|
||||
get(client::client &client,
|
||||
const char &letter,
|
||||
const std::string &key)
|
||||
{
|
||||
const uint8_t &idx(letter);
|
||||
const auto &conf(confs[idx]);
|
||||
if(unlikely(!conf))
|
||||
throw not_found("conf[%c] is not registered", letter);
|
||||
|
||||
return *reinterpret_cast<const T *>(conf->get(client, key));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T &
|
||||
get(client::client &client,
|
||||
const char &letter,
|
||||
const std::string &label,
|
||||
const std::string &key)
|
||||
{
|
||||
const uint8_t &idx(letter);
|
||||
const auto &conf(confs[idx]);
|
||||
if(unlikely(!conf))
|
||||
throw not_found("conf[%c] is not registered", letter);
|
||||
|
||||
return *reinterpret_cast<const T *>(conf->get(client, label, key));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::type_index
|
||||
make_index()
|
||||
{
|
||||
return typeid(typename std::add_pointer<T>::type);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
item::item(T *ptr):
|
||||
ptr{reinterpret_cast<uint8_t *>(ptr)},
|
||||
type{typeid(ptr)}
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace conf
|
||||
} // namespace ircd
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace ircd {
|
||||
namespace conf {
|
||||
|
@ -282,27 +381,6 @@ struct config_server_hide
|
|||
int disable_hidden;
|
||||
};
|
||||
|
||||
struct server_info
|
||||
{
|
||||
char *name;
|
||||
char sid[4];
|
||||
char *description;
|
||||
char *network_name;
|
||||
int hub;
|
||||
struct rb_sockaddr_storage bind4;
|
||||
int default_max_clients;
|
||||
#ifdef RB_IPV6
|
||||
struct rb_sockaddr_storage bind6;
|
||||
#endif
|
||||
char *ssl_private_key;
|
||||
char *ssl_ca_cert;
|
||||
char *ssl_cert;
|
||||
char *ssl_dh_params;
|
||||
char *ssl_cipher_list;
|
||||
int ssld_count;
|
||||
int wsockd_count;
|
||||
};
|
||||
|
||||
struct admin_info
|
||||
{
|
||||
char *name;
|
||||
|
|
|
@ -27,23 +27,37 @@ namespace ircd {
|
|||
namespace conf {
|
||||
namespace newconf {
|
||||
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
IRCD_EXCEPTION(error, unknown_block)
|
||||
|
||||
using key = std::string; // before the equals sign in an item
|
||||
using val = std::vector<std::string>; // Either one or more elems after '='
|
||||
using item = std::pair<key, val>; // Pairing of key/vals
|
||||
using block = std::pair<key, std::vector<item>>; // key is optional "label" { items };
|
||||
using topconf = std::multimap<key, block>; // key is type of block i.e admin { ... };
|
||||
using topconf = std::list<std::pair<key, block>>; // key is type of block i.e admin { ... };
|
||||
|
||||
/* Notes:
|
||||
* Some topconf entries are not blocks, but just key/values like "loadmodule." For this, the
|
||||
* topconf multimap contains keys of "loadmodule," and a block entry containing an empty key,
|
||||
* a vector of one item, with the item key also being "loadmodule" and the value being the
|
||||
* module to load.
|
||||
*
|
||||
* topconf is not an real multimap, but a vector preserving the important order of the config.
|
||||
*/
|
||||
|
||||
// Parse newconf syntax into tree
|
||||
topconf parse(const std::string &str);
|
||||
topconf parse(std::ifstream &file);
|
||||
topconf parse_file(const std::string &path);
|
||||
|
||||
// Translates newconf block names into characters
|
||||
using letters = std::array<std::string, 256>;
|
||||
extern letters registry;
|
||||
|
||||
uint8_t find_letter(const std::string &name);
|
||||
void translate(const topconf &, const std::function<void (std::string)> &closure);
|
||||
std::list<std::string> translate(const topconf &);
|
||||
|
||||
} // namespace newconf
|
||||
} // namespace conf
|
||||
} // namespace ircd
|
||||
|
|
288
ircd/conf.cc
288
ircd/conf.cc
|
@ -20,44 +20,60 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace ircd {
|
||||
namespace conf {
|
||||
|
||||
newconf::topconf newconf::current;
|
||||
newconf::topconf newconf::last;
|
||||
|
||||
struct log::log log
|
||||
{
|
||||
"conf", 'w' // both C's unavailable :/
|
||||
};
|
||||
|
||||
newconf::topconf newconf::current;
|
||||
newconf::topconf newconf::last;
|
||||
newconf::letters newconf::registry;
|
||||
std::array<top *, 256> confs;
|
||||
std::map<std::type_index, type_handler> type_handlers
|
||||
{
|
||||
{
|
||||
make_index<std::string>(), [](uint8_t *const &ptr, std::string text)
|
||||
{
|
||||
*reinterpret_cast<std::string *>(ptr) = std::move(text);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void reg(top *const &top);
|
||||
void unreg(top *const &top);
|
||||
bool execute(const std::string &line);
|
||||
void parse_newconf(const std::string &path);
|
||||
void bootstrap();
|
||||
|
||||
} // namespace conf
|
||||
} // namespace ircd
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
void conf::init(const std::string &path)
|
||||
void
|
||||
conf::init(const std::string &path)
|
||||
{
|
||||
newconf::registry['A'] = "admin";
|
||||
newconf::registry['B'] = "blacklist";
|
||||
newconf::registry['C'] = "connect";
|
||||
newconf::registry['I'] = "auth";
|
||||
newconf::registry['M'] = "serverinfo";
|
||||
newconf::registry['O'] = "operator";
|
||||
newconf::registry['P'] = "listen";
|
||||
newconf::registry['U'] = "service";
|
||||
newconf::registry['Y'] = "class";
|
||||
newconf::registry['a'] = "alias";
|
||||
newconf::registry['d'] = "exempt";
|
||||
newconf::registry['g'] = "general";
|
||||
newconf::registry['l'] = "log";
|
||||
newconf::registry['m'] = "loadmodule";
|
||||
|
||||
bootstrap();
|
||||
parse_newconf(path);
|
||||
const auto oldconf(newconf::translate(newconf::current));
|
||||
|
||||
// Translate to oldconf and linefeed
|
||||
newconf::translate(newconf::current, []
|
||||
(const std::string &line)
|
||||
{
|
||||
execute(line);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
conf::bootstrap()
|
||||
{
|
||||
log.debug("Bootstrapping L-Line module to load more modules...");
|
||||
mods::load("conf_loadmodule");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -67,54 +83,202 @@ conf::parse_newconf(const std::string &path)
|
|||
newconf::current = newconf::parse_file(path);
|
||||
}
|
||||
|
||||
std::forward_list<std::string>
|
||||
conf::newconf::translate(const newconf::topconf &top)
|
||||
bool
|
||||
conf::execute(const std::string &line)
|
||||
try
|
||||
{
|
||||
std::forward_list<std::string> ret;
|
||||
for(const auto &pair : top) try
|
||||
{
|
||||
const auto &type(pair.first);
|
||||
const auto &block(pair.second);
|
||||
const auto &label(block.first);
|
||||
const auto &items(block.second);
|
||||
const auto &letter(find_letter(type));
|
||||
for(const auto &item : items)
|
||||
{
|
||||
const auto &key(item.first);
|
||||
const auto &vals(item.second);
|
||||
std::stringstream buf;
|
||||
buf << letter << " "
|
||||
<< label << " "
|
||||
<< key << " :";
|
||||
|
||||
for(auto i(0); i < int(vals.size()) - 1; ++i)
|
||||
buf << vals.at(i) << " ";
|
||||
|
||||
if(!vals.empty())
|
||||
buf << vals.back();
|
||||
|
||||
ret.emplace_front(buf.str());
|
||||
}
|
||||
}
|
||||
catch(const error &e)
|
||||
{
|
||||
log.warning("%s", e.what());
|
||||
}
|
||||
|
||||
return ret;
|
||||
log.debug("%s", line.c_str());
|
||||
ircd::execute(me, line + "\r\n");
|
||||
return true;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log.error("%s", e.what());
|
||||
//return false;
|
||||
throw;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
conf::newconf::find_letter(const std::string &name)
|
||||
conf::top::top(const char &letter,
|
||||
const std::string &name,
|
||||
const items &list)
|
||||
:cmd{std::string{letter}}
|
||||
,letter{letter}
|
||||
,name{name}
|
||||
,map{begin(list), end(list)}
|
||||
{
|
||||
const auto ®istry(newconf::registry);
|
||||
const auto it(std::find(begin(registry), end(registry), name));
|
||||
if(it == end(registry))
|
||||
throw unknown_block("%s is not registered to a letter", name.c_str());
|
||||
|
||||
return std::distance(begin(registry), it);
|
||||
reg(this);
|
||||
}
|
||||
|
||||
conf::top::~top()
|
||||
noexcept
|
||||
{
|
||||
unreg(this);
|
||||
}
|
||||
|
||||
void
|
||||
conf::top::operator()(client::client &client,
|
||||
line line)
|
||||
try
|
||||
{
|
||||
if(line[0] == "*")
|
||||
set(client, std::move(line[1]), std::move(line[2]));
|
||||
else
|
||||
set(client, std::move(line[0]), std::move(line[1]), std::move(line[2]));
|
||||
}
|
||||
catch(const std::out_of_range &e)
|
||||
{
|
||||
//throw err::NEEDMOREPARAMS(me.id, id(me, client), command(line).c_str());
|
||||
throw error("NEEDMOREPARAMS");
|
||||
}
|
||||
catch(const boost::bad_lexical_cast &e)
|
||||
{
|
||||
throw bad_cast("conf[%c]: %s", letter, e.what());
|
||||
}
|
||||
|
||||
__attribute__((noreturn))
|
||||
void
|
||||
conf::top::enu(client::client &client,
|
||||
const std::string &label,
|
||||
const std::string &key)
|
||||
{
|
||||
throw bad_topconf("conf[%c] is a singleton and the label must be '*'", letter);
|
||||
}
|
||||
|
||||
__attribute__((noreturn))
|
||||
void
|
||||
conf::top::del(client::client &client,
|
||||
const std::string &label,
|
||||
const std::string &key)
|
||||
{
|
||||
throw bad_topconf("conf[%c] is a singleton and the label must be '*'", letter);
|
||||
}
|
||||
|
||||
void
|
||||
conf::top::set(client::client &client,
|
||||
std::string label,
|
||||
std::string key,
|
||||
std::string val)
|
||||
{
|
||||
throw bad_topconf("conf[%c] is a singleton and the label must be '*'", letter);
|
||||
}
|
||||
|
||||
__attribute__((noreturn))
|
||||
const uint8_t *
|
||||
conf::top::get(client::client &client,
|
||||
const std::string &label,
|
||||
const std::string &key)
|
||||
const
|
||||
{
|
||||
throw bad_topconf("conf[%c] is a singleton and the label must be '*'", letter);
|
||||
}
|
||||
|
||||
void
|
||||
conf::top::enu(client::client &client,
|
||||
const std::string &key)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
conf::top::del(client::client &client,
|
||||
const std::string &key)
|
||||
{
|
||||
if(!map.erase(key))
|
||||
log.warning("conf[%c] tried to erase non-existent key \"%s\"",
|
||||
letter,
|
||||
key.c_str());
|
||||
}
|
||||
|
||||
void
|
||||
conf::top::set(client::client &client,
|
||||
std::string key,
|
||||
std::string val)
|
||||
try
|
||||
{
|
||||
auto &item(map.at(key));
|
||||
assign(item, std::move(val));
|
||||
}
|
||||
catch(const std::out_of_range &e)
|
||||
{
|
||||
throw not_found("key \"%s\"", key.c_str());
|
||||
}
|
||||
catch(const boost::bad_lexical_cast &e)
|
||||
{
|
||||
throw bad_cast("conf[%c]: failed to set key \"%s\": %s",
|
||||
letter,
|
||||
key.c_str(),
|
||||
e.what());
|
||||
}
|
||||
|
||||
const uint8_t *
|
||||
conf::top::get(client::client &client,
|
||||
const std::string &key)
|
||||
const
|
||||
try
|
||||
{
|
||||
const auto &item(map.at(key));
|
||||
return item.ptr;
|
||||
}
|
||||
catch(const std::out_of_range &e)
|
||||
{
|
||||
throw not_found("key \"%s\"", key.c_str());
|
||||
}
|
||||
|
||||
void
|
||||
conf::top::assign(item &item,
|
||||
std::string val)
|
||||
const
|
||||
try
|
||||
{
|
||||
const auto &handler(type_handlers.at(item.type));
|
||||
handler(item.ptr, std::move(val));
|
||||
}
|
||||
catch(const std::out_of_range &e)
|
||||
{
|
||||
throw bad_cast("No handler to assign to value type \"%s\" @ %p",
|
||||
item.type.name(),
|
||||
item.ptr);
|
||||
}
|
||||
|
||||
void
|
||||
conf::unreg(top *const &top)
|
||||
{
|
||||
const auto &name(top->name);
|
||||
const auto &letter(top->letter);
|
||||
const uint8_t &idx(letter);
|
||||
|
||||
confs[idx] = nullptr;
|
||||
newconf::registry[idx].clear();
|
||||
|
||||
log.info("Unregistered configuration letter '%c' (%s)",
|
||||
letter,
|
||||
name.c_str());
|
||||
}
|
||||
|
||||
void
|
||||
conf::reg(top *const &top)
|
||||
{
|
||||
const auto &name(top->name);
|
||||
const auto &letter(top->letter);
|
||||
const uint8_t &idx(letter);
|
||||
if(!newconf::registry[idx].empty())
|
||||
throw already_exists("Configuration letter '%c' already registered for \"%s\"",
|
||||
letter,
|
||||
newconf::registry[idx].c_str());
|
||||
|
||||
const auto it(std::find(begin(newconf::registry), end(newconf::registry), name));
|
||||
if(it != end(newconf::registry))
|
||||
throw already_exists("Configuration letter '%c' already registered topconf \"%s\"",
|
||||
char(std::distance(begin(newconf::registry), it)),
|
||||
it->c_str());
|
||||
|
||||
newconf::registry[idx] = name;
|
||||
confs[idx] = top;
|
||||
|
||||
log.info("Registered configuration letter '%c' to conf type '%s'",
|
||||
letter,
|
||||
name.c_str());
|
||||
}
|
||||
|
||||
/*
|
||||
#define CF_TYPE(x) ((x) & CF_MTYPE)
|
||||
|
|
|
@ -21,8 +21,40 @@
|
|||
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
|
||||
namespace ircd {
|
||||
namespace conf {
|
||||
namespace newconf {
|
||||
|
||||
letters registry;
|
||||
|
||||
} // namespace newconf
|
||||
} // namespace conf
|
||||
} // namespace ircd
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
/*
|
||||
registry['A'] = "admin";
|
||||
registry['B'] = "blacklist";
|
||||
registry['C'] = "connect";
|
||||
registry['I'] = "auth";
|
||||
registry['O'] = "operator";
|
||||
registry['P'] = "listen";
|
||||
registry['U'] = "service";
|
||||
registry['Y'] = "class";
|
||||
registry['a'] = "alias";
|
||||
registry['d'] = "exempt";
|
||||
registry['g'] = "general";
|
||||
registry['l'] = "log";
|
||||
*/
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
using namespace qi;
|
||||
namespace ascii = qi::ascii;
|
||||
using qi::lexeme;
|
||||
using qi::char_;
|
||||
using qi::lit;
|
||||
using qi::eol;
|
||||
using qi::blank;
|
||||
|
||||
using str = std::string;
|
||||
using strvec = std::vector<str>;
|
||||
|
@ -31,7 +63,7 @@ using strvecvecvec = std::vector<strvecvec>;
|
|||
|
||||
template<class iter>
|
||||
struct ignores
|
||||
:grammar<iter>
|
||||
:qi::grammar<iter>
|
||||
{
|
||||
using rule = qi::rule<iter>;
|
||||
|
||||
|
@ -46,7 +78,7 @@ struct ignores
|
|||
template<class iter,
|
||||
class ignores>
|
||||
struct newconf_parser
|
||||
:grammar<iter, strvecvecvec(), ignores>
|
||||
:qi::grammar<iter, strvecvecvec(), ignores>
|
||||
{
|
||||
template<class ret> using rule = qi::rule<iter, ret, ignores>;
|
||||
|
||||
|
@ -185,8 +217,66 @@ ircd::conf::newconf::parse(const std::string &str)
|
|||
b.second.emplace_back(i);
|
||||
}
|
||||
|
||||
top.emplace(k, b);
|
||||
top.emplace_back(k, b);
|
||||
}
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
std::list<std::string>
|
||||
conf::newconf::translate(const topconf &top)
|
||||
{
|
||||
std::list<std::string> ret;
|
||||
translate(top, [&ret](std::string line)
|
||||
{
|
||||
ret.emplace_back(std::move(line));
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
conf::newconf::translate(const topconf &top,
|
||||
const std::function<void (std::string)> &closure)
|
||||
{
|
||||
for(const auto &pair : top) try
|
||||
{
|
||||
const auto &type(pair.first);
|
||||
const auto &block(pair.second);
|
||||
const auto &label(block.first);
|
||||
const auto &items(block.second);
|
||||
const auto &letter(find_letter(type));
|
||||
for(const auto &item : items)
|
||||
{
|
||||
const auto &key(item.first);
|
||||
const auto &vals(item.second);
|
||||
std::stringstream buf;
|
||||
buf << letter << " "
|
||||
<< label << " "
|
||||
<< key << " :";
|
||||
|
||||
for(auto i(0); i < int(vals.size()) - 1; ++i)
|
||||
buf << vals.at(i) << " ";
|
||||
|
||||
if(!vals.empty())
|
||||
buf << vals.back();
|
||||
|
||||
closure(buf.str());
|
||||
}
|
||||
}
|
||||
catch(const error &e)
|
||||
{
|
||||
log.warning("%s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
conf::newconf::find_letter(const std::string &name)
|
||||
{
|
||||
const auto ®istry(newconf::registry);
|
||||
const auto it(std::find(begin(registry), end(registry), name));
|
||||
if(it == end(registry))
|
||||
throw unknown_block("%s is not registered to a letter", name.c_str());
|
||||
|
||||
return std::distance(begin(registry), it);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
moduledir=@moduledir@
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/include \
|
||||
@BOOST_CPPFLAGS@ \
|
||||
|
@ -26,6 +24,20 @@ AM_LDFLAGS += \
|
|||
-lrb \
|
||||
@BOOST_LIBS@
|
||||
|
||||
|
||||
# This puts the source in conf/ but the installed
|
||||
# library is conf_X.so in the main modules dir.
|
||||
conf_moduledir=@moduledir@
|
||||
conf_conf_loadmodule_la_SOURCES = conf/loadmodule.cc
|
||||
conf_conf_serverinfo_la_SOURCES = conf/serverinfo.cc
|
||||
conf_conf_listen_la_SOURCES = conf/listen.cc
|
||||
conf_module_LTLIBRARIES = \
|
||||
conf/conf_loadmodule.la \
|
||||
conf/conf_serverinfo.la \
|
||||
conf/conf_listen.la
|
||||
|
||||
|
||||
moduledir=@moduledir@
|
||||
#m_ban_la_SOURCES = m_ban.cc
|
||||
#m_die_la_SOURCES = m_die.cc
|
||||
#m_error_la_SOURCES = m_error.cc
|
||||
|
|
83
modules/conf/listen.cc
Normal file
83
modules/conf/listen.cc
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"P-Line - configuration directives for listening sockets"
|
||||
};
|
||||
|
||||
struct P
|
||||
:conf::top
|
||||
{
|
||||
void set(client::client &, std::string label, std::string key, std::string val) override;
|
||||
|
||||
using conf::top::top;
|
||||
}
|
||||
|
||||
static P
|
||||
{
|
||||
'P', "listen",
|
||||
};
|
||||
|
||||
|
||||
struct block
|
||||
{
|
||||
std::string host;
|
||||
std::vector<uint16_t> port;
|
||||
};
|
||||
|
||||
std::map<std::string, block> blocks;
|
||||
|
||||
void
|
||||
P::set(client::client &,
|
||||
std::string label,
|
||||
std::string key,
|
||||
std::string val)
|
||||
{
|
||||
switch(hash(key))
|
||||
{
|
||||
case hash("host"):
|
||||
blocks[label].host = val;
|
||||
break;
|
||||
|
||||
case hash("port"):
|
||||
if(!val)
|
||||
{
|
||||
blocks[label].port.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
tokens(val, ", ", [&](const std::string &token)
|
||||
{
|
||||
const auto &val(boost::lexical_cast<uint16_t>(token));
|
||||
blocks[label].port.emplace_back(val);
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
conf::log.warning("Unknown P-Line key \"%s\"", key.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
76
modules/conf/loadmodule.cc
Normal file
76
modules/conf/loadmodule.cc
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"L-Line - configuration instruction for loadmodule"
|
||||
};
|
||||
|
||||
struct L
|
||||
:conf::top
|
||||
{
|
||||
void set(client::client &, std::string label, std::string key, std::string val) override;
|
||||
void del(client::client &, const std::string &label, const std::string &key) override;
|
||||
|
||||
using conf::top::top;
|
||||
}
|
||||
|
||||
static L
|
||||
{
|
||||
'L', "loadmodule"
|
||||
};
|
||||
|
||||
void
|
||||
L::set(client::client &client,
|
||||
std::string label,
|
||||
std::string key,
|
||||
std::string val)
|
||||
try
|
||||
{
|
||||
conf::log.debug("Loading \"%s\" via L-Line instruction", label.c_str());
|
||||
mods::load(label);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
conf::log.error("L-Line \"%s\": %s",
|
||||
label.c_str(),
|
||||
e.what());
|
||||
throw;
|
||||
}
|
||||
|
||||
void
|
||||
L::del(client::client &client,
|
||||
const std::string &label,
|
||||
const std::string &key)
|
||||
try
|
||||
{
|
||||
conf::log.debug("Unloading \"%s\" via L-Line instruction", label.c_str());
|
||||
mods::unload(label);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
conf::log.error("L-Line \"%s\": %s",
|
||||
label.c_str(),
|
||||
e.what());
|
||||
throw;
|
||||
}
|
47
modules/conf/serverinfo.cc
Normal file
47
modules/conf/serverinfo.cc
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string network_name;
|
||||
std::string sid;
|
||||
|
||||
std::string ssl_private_key;
|
||||
std::string ssl_ca_cert;
|
||||
std::string ssl_cert;
|
||||
std::string ssl_dh_params;
|
||||
std::string ssl_cipher_list;
|
||||
|
||||
int ssld_count;
|
||||
int wsockd_count;
|
||||
int default_max_clients;
|
||||
|
||||
conf::top M
|
||||
{
|
||||
'M', "serverinfo"
|
||||
};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"M-Line - configuration directives for serverinfo"
|
||||
};
|
Loading…
Reference in a new issue