mirror of
https://github.com/matrix-construct/construct
synced 2024-11-17 15:30:52 +01:00
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While MAPI III utilized a flexible key-value vector to eliminate positional arguments in a header initializer, now the developer simply makes a list of pointers to what they want to export for injection into IRCd. Example: mapi::header IRCD_MODULE { "mymod", "My module adds a command, a hook, and a CLICAP", &my_cmdtab, &some_hook, &clicaptab }; * Distributes the handlers for items passed to the above vector. Anyone can add a type-handler to the module system from anywhere in IRCd (and other modules?) When your type is encountered a handler is called providing the symbol name to read out of the module. Example in parser.cc: mods::add_loader<Message>([] (mod &loading, const std::string &symbol) { auto &msg(get<Message>(loading, symbol)); add_command(msg.name, msg); });
This commit is contained in:
parent
638db81e09
commit
9d0a959bb5
30 changed files with 1521 additions and 888 deletions
|
@ -317,6 +317,7 @@ RB_CHK_SYSHEADER([cstddef], [CSTDDEF])
|
||||||
RB_CHK_SYSHEADER([cstdint], [CSTDINT])
|
RB_CHK_SYSHEADER([cstdint], [CSTDINT])
|
||||||
RB_CHK_SYSHEADER([limits], [LIMITS])
|
RB_CHK_SYSHEADER([limits], [LIMITS])
|
||||||
RB_CHK_SYSHEADER([type_traits], [TYPE_TRAITS])
|
RB_CHK_SYSHEADER([type_traits], [TYPE_TRAITS])
|
||||||
|
RB_CHK_SYSHEADER([typeindex], [TYPEINDEX])
|
||||||
RB_CHK_SYSHEADER([utility], [UTILITY])
|
RB_CHK_SYSHEADER([utility], [UTILITY])
|
||||||
RB_CHK_SYSHEADER([functional], [FUNCTIONAL])
|
RB_CHK_SYSHEADER([functional], [FUNCTIONAL])
|
||||||
RB_CHK_SYSHEADER([algorithm], [ALGORITHM])
|
RB_CHK_SYSHEADER([algorithm], [ALGORITHM])
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
extensiondir=@moduledir@/extensions
|
extensiondir=@moduledir@
|
||||||
|
|
||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
|
@ -30,143 +30,144 @@ AM_LDFLAGS += \
|
||||||
@BOOST_LIBS@
|
@BOOST_LIBS@
|
||||||
|
|
||||||
|
|
||||||
chm_adminonly_la_SOURCES = chm_adminonly.cc
|
#chm_adminonly_la_SOURCES = chm_adminonly.cc
|
||||||
chm_operonly_la_SOURCES = chm_operonly.cc
|
#chm_operonly_la_SOURCES = chm_operonly.cc
|
||||||
chm_operonly_compat_la_SOURCES = chm_operonly_compat.cc
|
#chm_operonly_compat_la_SOURCES = chm_operonly_compat.cc
|
||||||
chm_insecure_la_SOURCES = chm_insecure.cc
|
#chm_insecure_la_SOURCES = chm_insecure.cc
|
||||||
chm_nonotice_la_SOURCES = chm_nonotice.cc
|
#chm_nonotice_la_SOURCES = chm_nonotice.cc
|
||||||
chm_operpeace_la_SOURCES = chm_operpeace.cc
|
#chm_operpeace_la_SOURCES = chm_operpeace.cc
|
||||||
chm_quietunreg_compat_la_SOURCES = chm_quietunreg_compat.cc
|
#chm_quietunreg_compat_la_SOURCES = chm_quietunreg_compat.cc
|
||||||
chm_spamfilter_la_SOURCES = chm_spamfilter.cc
|
#chm_spamfilter_la_SOURCES = chm_spamfilter.cc
|
||||||
chm_sslonly_la_SOURCES = chm_sslonly.cc
|
#chm_sslonly_la_SOURCES = chm_sslonly.cc
|
||||||
chm_sslonly_compat_la_SOURCES = chm_sslonly_compat.cc
|
#chm_sslonly_compat_la_SOURCES = chm_sslonly_compat.cc
|
||||||
createauthonly_la_SOURCES = createauthonly.cc
|
#createauthonly_la_SOURCES = createauthonly.cc
|
||||||
createoperonly_la_SOURCES = createoperonly.cc
|
#createoperonly_la_SOURCES = createoperonly.cc
|
||||||
extb_account_la_SOURCES = extb_account.cc
|
#extb_account_la_SOURCES = extb_account.cc
|
||||||
extb_canjoin_la_SOURCES = extb_canjoin.cc
|
#extb_canjoin_la_SOURCES = extb_canjoin.cc
|
||||||
extb_channel_la_SOURCES = extb_channel.cc
|
#extb_channel_la_SOURCES = extb_channel.cc
|
||||||
extb_hostmask_la_SOURCES = extb_hostmask.cc
|
#extb_hostmask_la_SOURCES = extb_hostmask.cc
|
||||||
extb_oper_la_SOURCES = extb_oper.cc
|
#extb_oper_la_SOURCES = extb_oper.cc
|
||||||
extb_server_la_SOURCES = extb_server.cc
|
#extb_server_la_SOURCES = extb_server.cc
|
||||||
extb_ssl_la_SOURCES = extb_ssl.cc
|
#extb_ssl_la_SOURCES = extb_ssl.cc
|
||||||
extb_realname_la_SOURCES = extb_realname.cc
|
#extb_realname_la_SOURCES = extb_realname.cc
|
||||||
extb_usermode_la_SOURCES = extb_usermode.cc
|
#extb_usermode_la_SOURCES = extb_usermode.cc
|
||||||
extb_extgecos_la_SOURCES = extb_extgecos.cc
|
#extb_extgecos_la_SOURCES = extb_extgecos.cc
|
||||||
extb_combi_la_SOURCES = extb_combi.cc
|
#extb_combi_la_SOURCES = extb_combi.cc
|
||||||
force_user_invis_la_SOURCES = force_user_invis.cc
|
#force_user_invis_la_SOURCES = force_user_invis.cc
|
||||||
helpops_la_SOURCES = helpops.cc
|
#helpops_la_SOURCES = helpops.cc
|
||||||
hurt_la_SOURCES = hurt.cc
|
#hurt_la_SOURCES = hurt.cc
|
||||||
ip_cloaking_la_SOURCES = ip_cloaking.cc
|
#ip_cloaking_la_SOURCES = ip_cloaking.cc
|
||||||
override_la_SOURCES = override.cc
|
#override_la_SOURCES = override.cc
|
||||||
restrict_unauthenticated_la_SOURCES = restrict-unauthenticated.cc
|
#restrict_unauthenticated_la_SOURCES = restrict-unauthenticated.cc
|
||||||
sno_channelcreate_la_SOURCES = sno_channelcreate.cc
|
#sno_channelcreate_la_SOURCES = sno_channelcreate.cc
|
||||||
sno_farconnect_la_SOURCES = sno_farconnect.cc
|
#sno_farconnect_la_SOURCES = sno_farconnect.cc
|
||||||
sno_globalkline_la_SOURCES = sno_globalkline.cc
|
#sno_globalkline_la_SOURCES = sno_globalkline.cc
|
||||||
sno_globalnickchange_la_SOURCES = sno_globalnickchange.cc
|
#sno_globalnickchange_la_SOURCES = sno_globalnickchange.cc
|
||||||
sno_globaloper_la_SOURCES = sno_globaloper.cc
|
#sno_globaloper_la_SOURCES = sno_globaloper.cc
|
||||||
sno_whois_la_SOURCES = sno_whois.cc
|
#sno_whois_la_SOURCES = sno_whois.cc
|
||||||
umode_noctcp_la_SOURCES = umode_noctcp.cc
|
#umode_noctcp_la_SOURCES = umode_noctcp.cc
|
||||||
m_adminwall_la_SOURCES = m_adminwall.cc
|
#m_adminwall_la_SOURCES = m_adminwall.cc
|
||||||
m_echotags_la_SOURCES = m_echotags.cc
|
#m_echotags_la_SOURCES = m_echotags.cc
|
||||||
m_extendchans_la_SOURCES = m_extendchans.cc
|
#m_extendchans_la_SOURCES = m_extendchans.cc
|
||||||
m_findforwards_la_SOURCES = m_findforwards.cc
|
#m_findforwards_la_SOURCES = m_findforwards.cc
|
||||||
m_identify_la_SOURCES = m_identify.cc
|
#m_identify_la_SOURCES = m_identify.cc
|
||||||
m_locops_la_SOURCES = m_locops.cc
|
#m_locops_la_SOURCES = m_locops.cc
|
||||||
m_mkpasswd_la_SOURCES = m_mkpasswd.cc
|
#m_mkpasswd_la_SOURCES = m_mkpasswd.cc
|
||||||
m_ojoin_la_SOURCES = m_ojoin.cc
|
#m_ojoin_la_SOURCES = m_ojoin.cc
|
||||||
m_okick_la_SOURCES = m_okick.cc
|
#m_okick_la_SOURCES = m_okick.cc
|
||||||
m_omode_la_SOURCES = m_omode.cc
|
#m_omode_la_SOURCES = m_omode.cc
|
||||||
m_opme_la_SOURCES = m_opme.cc
|
#m_opme_la_SOURCES = m_opme.cc
|
||||||
m_sendbans_la_SOURCES = m_sendbans.cc
|
#m_sendbans_la_SOURCES = m_sendbans.cc
|
||||||
m_webirc_la_SOURCES = m_webirc.cc
|
#m_webirc_la_SOURCES = m_webirc.cc
|
||||||
m_remove_la_SOURCES = m_remove.cc
|
#m_remove_la_SOURCES = m_remove.cc
|
||||||
m_roleplay_la_SOURCES = m_roleplay.cc
|
#m_roleplay_la_SOURCES = m_roleplay.cc
|
||||||
hide_uncommon_channels_la_SOURCES = hide_uncommon_channels.cc
|
#hide_uncommon_channels_la_SOURCES = hide_uncommon_channels.cc
|
||||||
no_kill_services_la_SOURCES = no_kill_services.cc
|
#no_kill_services_la_SOURCES = no_kill_services.cc
|
||||||
no_locops_la_SOURCES = no_locops.cc
|
#no_locops_la_SOURCES = no_locops.cc
|
||||||
no_oper_invis_la_SOURCES = no_oper_invis.cc
|
#no_oper_invis_la_SOURCES = no_oper_invis.cc
|
||||||
spamfilter_nicks_la_SOURCES = spamfilter_nicks.cc
|
#spamfilter_nicks_la_SOURCES = spamfilter_nicks.cc
|
||||||
spy_admin_notice_la_SOURCES = spy_admin_notice.cc
|
#spy_admin_notice_la_SOURCES = spy_admin_notice.cc
|
||||||
spy_info_notice_la_SOURCES = spy_info_notice.cc
|
#spy_info_notice_la_SOURCES = spy_info_notice.cc
|
||||||
spy_links_notice_la_SOURCES = spy_links_notice.cc
|
#spy_links_notice_la_SOURCES = spy_links_notice.cc
|
||||||
spy_motd_notice_la_SOURCES = spy_motd_notice.cc
|
#spy_motd_notice_la_SOURCES = spy_motd_notice.cc
|
||||||
spy_stats_notice_la_SOURCES = spy_stats_notice.cc
|
#spy_stats_notice_la_SOURCES = spy_stats_notice.cc
|
||||||
spy_stats_p_notice_la_SOURCES = spy_stats_p_notice.cc
|
#spy_stats_p_notice_la_SOURCES = spy_stats_p_notice.cc
|
||||||
spy_trace_notice_la_SOURCES = spy_trace_notice.cc
|
#spy_trace_notice_la_SOURCES = spy_trace_notice.cc
|
||||||
example_module_la_SOURCES = example_module.cc
|
#example_module_la_SOURCES = example_module.cc
|
||||||
|
|
||||||
|
|
||||||
extension_LTLIBRARIES = \
|
#extension_LTLIBRARIES = \
|
||||||
chm_adminonly.la \
|
# chm_adminonly.la \
|
||||||
chm_operonly.la \
|
# chm_operonly.la \
|
||||||
chm_operonly_compat.la \
|
# chm_operonly_compat.la \
|
||||||
chm_insecure.la \
|
# chm_insecure.la \
|
||||||
chm_nonotice.la \
|
# chm_nonotice.la \
|
||||||
chm_operpeace.la \
|
# chm_operpeace.la \
|
||||||
chm_quietunreg_compat.la \
|
# chm_quietunreg_compat.la \
|
||||||
chm_spamfilter.la \
|
# chm_spamfilter.la \
|
||||||
chm_sslonly.la \
|
# chm_sslonly.la \
|
||||||
chm_sslonly_compat.la \
|
# chm_sslonly_compat.la \
|
||||||
createauthonly.la \
|
# createauthonly.la \
|
||||||
createoperonly.la \
|
# createoperonly.la \
|
||||||
extb_account.la \
|
# extb_account.la \
|
||||||
extb_canjoin.la \
|
# extb_canjoin.la \
|
||||||
extb_channel.la \
|
# extb_channel.la \
|
||||||
extb_hostmask.la \
|
# extb_hostmask.la \
|
||||||
extb_oper.la \
|
# extb_oper.la \
|
||||||
extb_server.la \
|
# extb_server.la \
|
||||||
extb_ssl.la \
|
# extb_ssl.la \
|
||||||
extb_realname.la \
|
# extb_realname.la \
|
||||||
extb_usermode.la \
|
# extb_usermode.la \
|
||||||
extb_extgecos.la \
|
# extb_extgecos.la \
|
||||||
extb_combi.la \
|
# extb_combi.la \
|
||||||
force_user_invis.la \
|
# force_user_invis.la \
|
||||||
helpops.la \
|
# helpops.la \
|
||||||
hurt.la \
|
# hurt.la \
|
||||||
ip_cloaking.la \
|
# ip_cloaking.la \
|
||||||
override.la \
|
# override.la \
|
||||||
restrict-unauthenticated.la \
|
# restrict-unauthenticated.la \
|
||||||
sno_channelcreate.la \
|
# sno_channelcreate.la \
|
||||||
sno_farconnect.la \
|
# sno_farconnect.la \
|
||||||
sno_globalkline.la \
|
# sno_globalkline.la \
|
||||||
sno_globalnickchange.la \
|
# sno_globalnickchange.la \
|
||||||
sno_globaloper.la \
|
# sno_globaloper.la \
|
||||||
sno_whois.la \
|
# sno_whois.la \
|
||||||
umode_noctcp.la \
|
# umode_noctcp.la \
|
||||||
m_adminwall.la \
|
# m_adminwall.la \
|
||||||
m_echotags.la \
|
# m_echotags.la \
|
||||||
m_extendchans.la \
|
# m_extendchans.la \
|
||||||
m_findforwards.la \
|
# m_findforwards.la \
|
||||||
m_identify.la \
|
# m_identify.la \
|
||||||
m_locops.la \
|
# m_locops.la \
|
||||||
m_mkpasswd.la \
|
# m_mkpasswd.la \
|
||||||
m_ojoin.la \
|
# m_ojoin.la \
|
||||||
m_okick.la \
|
# m_okick.la \
|
||||||
m_omode.la \
|
# m_omode.la \
|
||||||
m_opme.la \
|
# m_opme.la \
|
||||||
m_sendbans.la \
|
# m_sendbans.la \
|
||||||
m_webirc.la \
|
# m_webirc.la \
|
||||||
m_remove.la \
|
# m_remove.la \
|
||||||
m_roleplay.la \
|
# m_roleplay.la \
|
||||||
hide_uncommon_channels.la \
|
# hide_uncommon_channels.la \
|
||||||
no_kill_services.la \
|
# no_kill_services.la \
|
||||||
no_locops.la \
|
# no_locops.la \
|
||||||
no_oper_invis.la \
|
# no_oper_invis.la \
|
||||||
spamfilter_nicks.la \
|
# spamfilter_nicks.la \
|
||||||
spy_admin_notice.la \
|
# spy_admin_notice.la \
|
||||||
spy_info_notice.la \
|
# spy_info_notice.la \
|
||||||
spy_links_notice.la \
|
# spy_links_notice.la \
|
||||||
spy_motd_notice.la \
|
# spy_motd_notice.la \
|
||||||
spy_stats_notice.la \
|
# spy_stats_notice.la \
|
||||||
spy_stats_p_notice.la \
|
# spy_stats_p_notice.la \
|
||||||
spy_trace_notice.la \
|
# spy_trace_notice.la \
|
||||||
example_module.la
|
# example_module.la
|
||||||
|
#
|
||||||
if PCRE
|
#if PCRE
|
||||||
|
#
|
||||||
extension_LTLIBRARIES += spamfilter_expr.la
|
#extension_LTLIBRARIES += spamfilter_expr.la
|
||||||
spamfilter_expr_la_SOURCES = spamfilter_expr.cc
|
#spamfilter_expr_la_SOURCES = spamfilter_expr.cc
|
||||||
spamfilter_expr_la_CPPFLAGS = $(AM_CPPFLAGS) $(PCRE_CFLAGS)
|
#spamfilter_expr_la_CPPFLAGS = $(AM_CPPFLAGS) $(PCRE_CFLAGS)
|
||||||
spamfilter_expr_la_LIBADD = $(PCRE_LIBS)
|
#spamfilter_expr_la_LIBADD = $(PCRE_LIBS)
|
||||||
|
#
|
||||||
endif
|
#endif
|
||||||
|
#
|
||||||
|
|
|
@ -46,8 +46,6 @@ namespace fs {
|
||||||
constexpr auto DPATH = IRCD_PREFIX;
|
constexpr auto DPATH = IRCD_PREFIX;
|
||||||
constexpr auto BINPATH = IRCD_PREFIX "/bin";
|
constexpr auto BINPATH = IRCD_PREFIX "/bin";
|
||||||
constexpr auto MODPATH = RB_MODULE_DIR;
|
constexpr auto MODPATH = RB_MODULE_DIR;
|
||||||
constexpr auto MODULE_DIR = RB_MODULE_DIR;
|
|
||||||
constexpr auto AUTOMODPATH = RB_MODULE_DIR "/autoload";
|
|
||||||
constexpr auto ETCPATH = RB_ETC_DIR;
|
constexpr auto ETCPATH = RB_ETC_DIR;
|
||||||
constexpr auto LOGPATH = RB_LOG_DIR;
|
constexpr auto LOGPATH = RB_LOG_DIR;
|
||||||
constexpr auto UHPATH = RB_HELP_DIR "/users";
|
constexpr auto UHPATH = RB_HELP_DIR "/users";
|
||||||
|
@ -71,7 +69,6 @@ namespace path
|
||||||
LOG,
|
LOG,
|
||||||
LIBEXEC,
|
LIBEXEC,
|
||||||
MODULES,
|
MODULES,
|
||||||
AUTOLOAD_MODULES,
|
|
||||||
USERHELP,
|
USERHELP,
|
||||||
OPERHELP,
|
OPERHELP,
|
||||||
IRCD_CONF,
|
IRCD_CONF,
|
||||||
|
|
116
include/ircd/mapi.h
Normal file
116
include/ircd/mapi.h
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define HAVE_IRCD_MAPI_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace ircd {
|
||||||
|
namespace mapi {
|
||||||
|
|
||||||
|
struct init
|
||||||
|
:std::function<void ()>
|
||||||
|
{
|
||||||
|
using std::function<void ()>::function;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fini
|
||||||
|
:std::function<void ()>
|
||||||
|
{
|
||||||
|
using std::function<void ()>::function;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum flags
|
||||||
|
{
|
||||||
|
NO_FLAGS = 0x00,
|
||||||
|
RELAXED_INIT = 0x01,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Associates RTTI keyed by object location
|
||||||
|
using export_vector = std::vector<std::pair<const void *, std::type_index>>;
|
||||||
|
|
||||||
|
struct exports
|
||||||
|
:export_vector
|
||||||
|
{
|
||||||
|
template<class... List> exports(List&&... list);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct header
|
||||||
|
{
|
||||||
|
static const char *const sym_name;
|
||||||
|
static constexpr const magic_t MAGIC
|
||||||
|
{
|
||||||
|
0x4D41
|
||||||
|
};
|
||||||
|
|
||||||
|
magic_t magic; // The magic must match MAGIC
|
||||||
|
version_t version; // Version indicator
|
||||||
|
enum flags flags; // Option flags
|
||||||
|
int64_t timestamp; // Module's compile epoch
|
||||||
|
const char *desc;
|
||||||
|
struct exports exports;
|
||||||
|
|
||||||
|
template<class... Exports>
|
||||||
|
header(const char *const &desc,
|
||||||
|
const enum flags &flags,
|
||||||
|
Exports&&... exports);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class... Exports>
|
||||||
|
header::header(const char *const &desc,
|
||||||
|
const enum flags &flags,
|
||||||
|
Exports&&... exports)
|
||||||
|
:magic(MAGIC)
|
||||||
|
,version(4)
|
||||||
|
,flags(flags)
|
||||||
|
,timestamp(RB_DATECODE)
|
||||||
|
,desc(desc)
|
||||||
|
,exports{std::forward<Exports>(exports)...}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *const
|
||||||
|
header::sym_name
|
||||||
|
{
|
||||||
|
"IRCD_MODULE"
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class... List>
|
||||||
|
exports::exports(List&&... list)
|
||||||
|
{
|
||||||
|
const std::vector<std::type_index> types
|
||||||
|
{
|
||||||
|
typeid(List)...
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<const void *> ptrs
|
||||||
|
{
|
||||||
|
std::forward<List>(list)...
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(types.size() == ptrs.size());
|
||||||
|
for(size_t i(0); i < types.size(); ++i)
|
||||||
|
this->emplace_back(ptrs.at(i), types.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mapi
|
||||||
|
} // namespace ircd
|
||||||
|
#endif // __cplusplus
|
|
@ -1,10 +1,12 @@
|
||||||
/*
|
/*
|
||||||
* ircd-ratbox: A slightly useful ircd.
|
* IRCd (Charybdis): Pushing the envelope since '88
|
||||||
* modules.h: A header for the modules functions.
|
* modules.h: A header for the modules functions.
|
||||||
*
|
*
|
||||||
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
* Copyright (C) 1996-2002 Hybrid Development Team
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
* Copyright (C) 2002-2004 ircd-ratbox development team
|
* Copyright (C) 2002-2004 ircd-ratbox development team
|
||||||
|
* Copyright (C) 2016 Charybdis Development Team
|
||||||
|
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,173 +27,160 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#define HAVE_IRCD_MODULES_H
|
#define HAVE_IRCD_MODULES_H
|
||||||
|
|
||||||
#define MAPI_CHARYBDIS 2
|
|
||||||
typedef struct lt__handle *lt_dlhandle;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
namespace ircd {
|
namespace ircd {
|
||||||
|
namespace mapi {
|
||||||
|
|
||||||
struct module
|
using magic_t = uint16_t;
|
||||||
|
using version_t = uint16_t;
|
||||||
|
struct header;
|
||||||
|
|
||||||
|
} // namespace mapi
|
||||||
|
|
||||||
|
namespace mods {
|
||||||
|
|
||||||
|
using mapi::magic_t;
|
||||||
|
using mapi::version_t;
|
||||||
|
|
||||||
|
IRCD_EXCEPTION(ircd::error, error)
|
||||||
|
IRCD_EXCEPTION(error, filesystem_error)
|
||||||
|
IRCD_EXCEPTION(error, invalid_export)
|
||||||
|
|
||||||
|
struct mod;
|
||||||
|
bool has(const mod &mod, const std::string &symbol);
|
||||||
|
const uint8_t *ptr(const mod &mod, const std::string &symbol);
|
||||||
|
uint8_t *ptr(mod &mod, const std::string &symbol);
|
||||||
|
template<class T> const T *ptr(const mod &mod, const std::string &symbol);
|
||||||
|
template<class T> const T &get(const mod &mod, const std::string &symbol);
|
||||||
|
template<class T> T *ptr(mod &mod, const std::string &symbol);
|
||||||
|
template<class T> T &get(mod &mod, const std::string &symbol);
|
||||||
|
const mapi::header &header(const mod &);
|
||||||
|
const char *const &desc(const mod &);
|
||||||
|
const version_t &version(const mod &);
|
||||||
|
const int64_t ×tamp(const mod &);
|
||||||
|
std::string location(const mod &);
|
||||||
|
std::string name(const mod &);
|
||||||
|
|
||||||
|
extern struct log::log log;
|
||||||
|
|
||||||
|
// Symbol handlers
|
||||||
|
struct type_handlers
|
||||||
{
|
{
|
||||||
const char *name;
|
std::function<void (mod &, const std::string &sym)> loader;
|
||||||
const char *path;
|
std::function<void (mod &, const std::string &sym)> unloader;
|
||||||
const char *version;
|
std::function<void (mod &, const std::string &sym)> reloader;
|
||||||
const char *description;
|
|
||||||
lt_dlhandle address;
|
|
||||||
int core; /* This is int for backwards compat reasons */
|
|
||||||
int origin; /* Ditto */
|
|
||||||
int mapi_version;
|
|
||||||
void *mapi_header; /* actually struct mapi_mheader_av<mapi_version> */
|
|
||||||
rb_dlink_node node;
|
|
||||||
};
|
};
|
||||||
|
template<class T> std::type_index make_index();
|
||||||
|
bool add(const std::type_index &, const type_handlers &handlers);
|
||||||
|
bool del(const std::type_index &);
|
||||||
|
bool has(const std::type_index &);
|
||||||
|
template<class T, class... type_handlers> bool add(type_handlers&&... handlers);
|
||||||
|
template<class T> bool del();
|
||||||
|
template<class T> bool has();
|
||||||
|
|
||||||
#define MAPI_MAGIC_HDR 0x4D410000
|
// The search path vector
|
||||||
|
std::vector<std::string> paths();
|
||||||
|
bool path_added(const std::string &dir);
|
||||||
|
void path_del(const std::string &dir);
|
||||||
|
bool path_add(const std::string &dir, std::nothrow_t); // logs errors and returns false
|
||||||
|
bool path_add(const std::string &dir); // false if exists, throws other errors
|
||||||
|
void path_clear();
|
||||||
|
|
||||||
#define MAPI_V1 (MAPI_MAGIC_HDR | 0x1)
|
// Dump object data
|
||||||
#define MAPI_V2 (MAPI_MAGIC_HDR | 0x2)
|
std::vector<std::string> symbols(const std::string &fullpath, const std::string §ion);
|
||||||
#define MAPI_V3 (MAPI_MAGIC_HDR | 0x3)
|
std::vector<std::string> symbols(const std::string &fullpath);
|
||||||
|
std::vector<std::string> sections(const std::string &fullpath);
|
||||||
|
|
||||||
#define MAPI_MAGIC(x) ((x) & 0xffff0000)
|
// Checks if loadable module containing a mapi header (does not verify the magic)
|
||||||
#define MAPI_VERSION(x) ((x) & 0x0000ffff)
|
bool is_module(const std::string &fullpath, std::string &why);
|
||||||
|
bool is_module(const std::string &fullpath, std::nothrow_t);
|
||||||
|
bool is_module(const std::string &fullpath);
|
||||||
|
|
||||||
typedef struct Message* mapi_clist_av1;
|
// returns dir/name of first dir containing 'name' (and this will be a loadable module)
|
||||||
|
// Unlike libltdl, the reason each individual candidate failed is presented in a vector.
|
||||||
|
std::string search(const std::string &name, std::vector<std::string> &why);
|
||||||
|
std::string search(const std::string &name);
|
||||||
|
|
||||||
typedef struct
|
// Potential modules available to load
|
||||||
|
std::forward_list<std::string> available();
|
||||||
|
bool available(const std::string &name);
|
||||||
|
|
||||||
|
// Find module names where symbol resides
|
||||||
|
bool has_symbol(const std::string &name, const std::string &symbol);
|
||||||
|
std::vector<std::string> find_symbol(const std::string &symbol);
|
||||||
|
|
||||||
|
// Modules currently loaded
|
||||||
|
const std::map<std::string, std::unique_ptr<mod>> &loaded();
|
||||||
|
bool loaded(const std::string &name);
|
||||||
|
mod &get(const std::string &name);
|
||||||
|
|
||||||
|
bool reload(const std::string name);
|
||||||
|
bool unload(const std::string name);
|
||||||
|
bool load(const std::string &name);
|
||||||
|
void autoload();
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
bool
|
||||||
|
has()
|
||||||
{
|
{
|
||||||
const char *hapi_name;
|
return has(make_index<T>());
|
||||||
int *hapi_id;
|
}
|
||||||
} mapi_hlist_av1;
|
|
||||||
|
|
||||||
typedef struct
|
template<class T>
|
||||||
|
bool
|
||||||
|
del()
|
||||||
{
|
{
|
||||||
const char *hapi_name;
|
return del(make_index<T>());
|
||||||
hookfn fn;
|
}
|
||||||
} mapi_hfn_list_av1;
|
|
||||||
|
|
||||||
|
template<class T,
|
||||||
#define MAPI_CAP_CLIENT 1
|
class... type_handlers>
|
||||||
#define MAPI_CAP_SERVER 2
|
bool
|
||||||
|
add(type_handlers&&... handlers)
|
||||||
typedef struct
|
|
||||||
{
|
{
|
||||||
int cap_index; /* Which cap index does this belong to? */
|
return add(make_index<T>(), {std::forward<type_handlers>(handlers)...});
|
||||||
const char *cap_name; /* Capability name */
|
}
|
||||||
void *cap_ownerdata; /* Not used much but why not... */
|
|
||||||
unsigned int *cap_id; /* May be set to non-NULL to store cap id */
|
|
||||||
} mapi_cap_list_av2;
|
|
||||||
|
|
||||||
struct mapi_mheader_av1
|
template<class T>
|
||||||
|
std::type_index
|
||||||
|
make_index()
|
||||||
{
|
{
|
||||||
int mapi_version; /* Module API version */
|
return typeid(typename std::add_pointer<T>::type);
|
||||||
int (*mapi_register)(void); /* Register function; ret -1 = failure (unload) */
|
}
|
||||||
void (*mapi_unregister)(void); /* Unregister function. */
|
|
||||||
mapi_clist_av1 *mapi_command_list; /* List of commands to add. */
|
|
||||||
mapi_hlist_av1 *mapi_hook_list; /* List of hooks to add. */
|
|
||||||
mapi_hfn_list_av1 *mapi_hfn_list; /* List of hook_add_hook's to do */
|
|
||||||
const char *mapi_module_version; /* Module's version (freeform) */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAPI_ORIGIN_UNKNOWN 0 /* Unknown provenance (AV1 etc.) */
|
template<class T>
|
||||||
#define MAPI_ORIGIN_EXTENSION 1 /* Charybdis extension */
|
T &
|
||||||
#define MAPI_ORIGIN_CORE 2 /* Charybdis core module */
|
get(mod &mod,
|
||||||
|
const std::string &symbol)
|
||||||
struct mapi_mheader_av2
|
|
||||||
{
|
{
|
||||||
int mapi_version; /* Module API version */
|
return *reinterpret_cast<T *>(ptr(mod, symbol));
|
||||||
int (*mapi_register)(void); /* Register function; ret -1 = failure (unload) */
|
}
|
||||||
void (*mapi_unregister)(void); /* Unregister function. */
|
|
||||||
mapi_clist_av1 *mapi_command_list; /* List of commands to add. */
|
|
||||||
mapi_hlist_av1 *mapi_hook_list; /* List of hooks to add. */
|
|
||||||
mapi_hfn_list_av1 *mapi_hfn_list; /* List of hook_add_hook's to do */
|
|
||||||
mapi_cap_list_av2 *mapi_cap_list; /* List of CAPs to add */
|
|
||||||
const char *mapi_module_version; /* Module's version (freeform), replaced with ircd version if NULL */
|
|
||||||
const char *mapi_module_description; /* Module's description (freeform) */
|
|
||||||
time_t mapi_datecode; /* Unix timestamp of module's build */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DECLARE_MODULE_AV1(name, reg, unreg, cl, hl, hfnlist, v) \
|
template<class T>
|
||||||
struct mapi_mheader_av1 _mheader = { MAPI_V1, reg, unreg, cl, hl, hfnlist, v}
|
T *
|
||||||
|
ptr(mod &mod,
|
||||||
#define DECLARE_MODULE_AV2(name, reg, unreg, cl, hl, hfnlist, caplist, v, desc) \
|
const std::string &symbol)
|
||||||
struct mapi_mheader_av2 _mheader = { MAPI_V2, reg, unreg, cl, hl, hfnlist, caplist, v, desc, RB_DATECODE}
|
|
||||||
|
|
||||||
|
|
||||||
/***
|
|
||||||
Version 3 modules utilize a flexible key/value vector.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
DECLARE_MODULE_AV3
|
|
||||||
(
|
|
||||||
MOD_ATTR { "name", "mymodule" },
|
|
||||||
MOD_ATTR { "mtab", &message_foo },
|
|
||||||
MOD_ATTR { "mtab", &message_unfoo },
|
|
||||||
MOD_ATTR { "init", modinitfunc },
|
|
||||||
MOD_ATTR { "hook", MOD_HOOK { "myhook", &id } },
|
|
||||||
MOD_ATTR { "hookfn", MOD_HOOKFN { "myhook", hookfun } },
|
|
||||||
)
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
- Multiple keys with the same name will have different behavior depending on the logic for that key.
|
|
||||||
- On load, the order in which keys are specified is the order they will be evaluated (top to bottom).
|
|
||||||
- On unload, the evaluation is the REVERSE order (bottom to top).
|
|
||||||
- If an init function returns false, or other error occurs, no further keys are evaluated and the
|
|
||||||
unload rolls back from that point.
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct mapi_av3_attr
|
|
||||||
{
|
{
|
||||||
#define MAPI_V3_KEY_MAXLEN 16 /* Maximum length for a key string */
|
return reinterpret_cast<T *>(ptr(mod, symbol));
|
||||||
|
}
|
||||||
|
|
||||||
const char *key;
|
template<class T>
|
||||||
union { const void *cvalue; void *value; int (*init)(void); void (*fini)(void); };
|
const T &
|
||||||
};
|
get(const mod &mod,
|
||||||
|
const std::string &symbol)
|
||||||
struct mapi_mheader_av3
|
|
||||||
{
|
{
|
||||||
int mapi_version; // Module API version
|
return *reinterpret_cast<const T *>(ptr(mod, symbol));
|
||||||
struct mapi_av3_attr **attrs; // A vector of attributes, NULL terminated
|
}
|
||||||
};
|
|
||||||
|
|
||||||
#define MOD_ATTR &(struct mapi_av3_attr)
|
template<class T>
|
||||||
#define MOD_HOOK &(mapi_hlist_av1)
|
const T *
|
||||||
#define MOD_HOOKFN &(mapi_hfn_list_av1)
|
ptr(const mod &mod,
|
||||||
|
const std::string &symbol)
|
||||||
#define DECLARE_MODULE_AV3(...) \
|
{
|
||||||
struct mapi_mheader_av3 _mheader = \
|
return reinterpret_cast<const T *>(ptr(mod, symbol));
|
||||||
{ \
|
}
|
||||||
MAPI_V3, (struct mapi_av3_attr *[]) \
|
|
||||||
{ \
|
|
||||||
MOD_ATTR { "time", RB_DATECODE },\
|
|
||||||
__VA_ARGS__, \
|
|
||||||
NULL \
|
|
||||||
} \
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Prefixes your slog() message with module info
|
|
||||||
void module_log(struct module *mod, const char *fmt, ...) AFP(2, 3);
|
|
||||||
|
|
||||||
/* add a path */
|
|
||||||
void mod_add_path(const char *path);
|
|
||||||
void mod_clear_paths(void);
|
|
||||||
|
|
||||||
/* load a module */
|
|
||||||
extern void load_module(char *path);
|
|
||||||
|
|
||||||
/* load all modules */
|
|
||||||
extern void load_all_modules(bool warn);
|
|
||||||
|
|
||||||
/* load core modules */
|
|
||||||
extern void load_core_modules(bool);
|
|
||||||
|
|
||||||
extern bool unload_one_module(const char *, bool);
|
|
||||||
bool load_one_module(const char *, int, bool);
|
|
||||||
extern bool load_a_module(const char *, bool, int, bool);
|
|
||||||
struct module *findmodule_byname(const char *);
|
|
||||||
extern void init_modules(void);
|
|
||||||
|
|
||||||
extern rb_dlink_list module_list;
|
|
||||||
extern rb_dlink_list mod_paths;
|
|
||||||
|
|
||||||
|
} // namespace mods
|
||||||
} // namespace ircd
|
} // namespace ircd
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
|
@ -32,6 +32,8 @@ namespace ircd
|
||||||
using std::begin;
|
using std::begin;
|
||||||
using std::end;
|
using std::end;
|
||||||
using std::get;
|
using std::get;
|
||||||
|
using ostream = std::ostream;
|
||||||
|
using namespace std::string_literals;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temp fwd decl scaffold
|
// Temp fwd decl scaffold
|
||||||
|
@ -60,8 +62,6 @@ namespace ircd
|
||||||
struct ev_ctl;
|
struct ev_ctl;
|
||||||
struct ws_ctl;
|
struct ws_ctl;
|
||||||
struct server_conf;
|
struct server_conf;
|
||||||
|
|
||||||
using ostream = std::ostream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
|
@ -58,6 +58,7 @@ extern "C" {
|
||||||
#include <RB_INC_CSTDINT
|
#include <RB_INC_CSTDINT
|
||||||
#include <RB_INC_LIMITS
|
#include <RB_INC_LIMITS
|
||||||
#include <RB_INC_TYPE_TRAITS
|
#include <RB_INC_TYPE_TRAITS
|
||||||
|
#include <RB_INC_TYPEINDEX
|
||||||
#include <RB_INC_CERRNO
|
#include <RB_INC_CERRNO
|
||||||
#include <RB_INC_UTILITY
|
#include <RB_INC_UTILITY
|
||||||
#include <RB_INC_FUNCTIONAL
|
#include <RB_INC_FUNCTIONAL
|
||||||
|
@ -72,7 +73,7 @@ extern "C" {
|
||||||
#include <RB_INC_MAP
|
#include <RB_INC_MAP
|
||||||
#include <RB_INC_SET
|
#include <RB_INC_SET
|
||||||
#include <RB_INC_LIST
|
#include <RB_INC_LIST
|
||||||
//#include <RB_INC_FORWARD_LIST
|
#include <RB_INC_FORWARD_LIST
|
||||||
//#include <RB_INC_UNORDERED_MAP
|
//#include <RB_INC_UNORDERED_MAP
|
||||||
//#include <RB_INC_DEQUE
|
//#include <RB_INC_DEQUE
|
||||||
#include <RB_INC_SSTREAM
|
#include <RB_INC_SSTREAM
|
||||||
|
|
|
@ -35,7 +35,6 @@ auto paths = []
|
||||||
|
|
||||||
paths[PREFIX] = DPATH;
|
paths[PREFIX] = DPATH;
|
||||||
paths[MODULES] = MODPATH;
|
paths[MODULES] = MODPATH;
|
||||||
paths[AUTOLOAD_MODULES] = AUTOMODPATH;
|
|
||||||
paths[ETC] = ETCPATH;
|
paths[ETC] = ETCPATH;
|
||||||
paths[LOG] = LOGPATH;
|
paths[LOG] = LOGPATH;
|
||||||
paths[USERHELP] = UHPATH;
|
paths[USERHELP] = UHPATH;
|
||||||
|
@ -62,7 +61,6 @@ auto pathnames = []
|
||||||
|
|
||||||
names[PREFIX] = "prefix";
|
names[PREFIX] = "prefix";
|
||||||
names[MODULES] = "modules";
|
names[MODULES] = "modules";
|
||||||
names[AUTOLOAD_MODULES] = "autoload modules";
|
|
||||||
names[ETC] = "config";
|
names[ETC] = "config";
|
||||||
names[LOG] = "log";
|
names[LOG] = "log";
|
||||||
names[USERHELP] = "user help";
|
names[USERHELP] = "user help";
|
||||||
|
@ -139,9 +137,6 @@ void relocate()
|
||||||
snprintf(workbuf, sizeof workbuf, "%s%cmodules", prefix, RB_PATH_SEPARATOR);
|
snprintf(workbuf, sizeof workbuf, "%s%cmodules", prefix, RB_PATH_SEPARATOR);
|
||||||
paths[MODULES] = rb_strdup(workbuf);
|
paths[MODULES] = rb_strdup(workbuf);
|
||||||
|
|
||||||
snprintf(workbuf, sizeof workbuf, "%s%cmodules%cautoload", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
|
|
||||||
paths[AUTOLOAD_MODULES] = rb_strdup(workbuf);
|
|
||||||
|
|
||||||
snprintf(workbuf, sizeof workbuf, "%s%cetc", prefix, RB_PATH_SEPARATOR);
|
snprintf(workbuf, sizeof workbuf, "%s%cetc", prefix, RB_PATH_SEPARATOR);
|
||||||
paths[ETC] = rb_strdup(workbuf);
|
paths[ETC] = rb_strdup(workbuf);
|
||||||
|
|
||||||
|
|
|
@ -549,7 +549,6 @@ charybdis_main(int argc, char * const argv[])
|
||||||
|
|
||||||
init_authd(); /* Start up authd. */
|
init_authd(); /* Start up authd. */
|
||||||
init_dns(); /* Start up DNS query system */
|
init_dns(); /* Start up DNS query system */
|
||||||
init_modules(); /* Start up modules system */
|
|
||||||
|
|
||||||
privilegeset_set_new("default", "", 0);
|
privilegeset_set_new("default", "", 0);
|
||||||
|
|
||||||
|
@ -557,8 +556,7 @@ charybdis_main(int argc, char * const argv[])
|
||||||
fprintf(stderr, "\nBeginning config test\n");
|
fprintf(stderr, "\nBeginning config test\n");
|
||||||
read_conf_files(true); /* cold start init conf files */
|
read_conf_files(true); /* cold start init conf files */
|
||||||
|
|
||||||
load_all_modules(1);
|
mods::autoload();
|
||||||
load_core_modules(1);
|
|
||||||
|
|
||||||
supported::init();
|
supported::init();
|
||||||
|
|
||||||
|
|
|
@ -276,9 +276,9 @@ loadmodule:
|
||||||
char *m_bn;
|
char *m_bn;
|
||||||
m_bn = rb_basename((char *) $2);
|
m_bn = rb_basename((char *) $2);
|
||||||
|
|
||||||
if (ircd::findmodule_byname(m_bn) == NULL)
|
if (!ircd::mods::loaded(m_bn))
|
||||||
{
|
{
|
||||||
ircd::load_one_module($2, MAPI_ORIGIN_EXTENSION, 0);
|
ircd::mods::load($2);
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_free(m_bn);
|
rb_free(m_bn);
|
||||||
|
|
191
ircd/mods_mod.h
Normal file
191
ircd/mods_mod.h
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define HAVE_IRCD_MODS_MOD_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace ircd {
|
||||||
|
namespace mods {
|
||||||
|
|
||||||
|
struct sym
|
||||||
|
{
|
||||||
|
std::type_index type;
|
||||||
|
|
||||||
|
sym(const std::type_index &type)
|
||||||
|
:type{type}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mod
|
||||||
|
{
|
||||||
|
boost::dll::shared_library handle;
|
||||||
|
const mapi::header *header;
|
||||||
|
std::map<std::string, sym> handled;
|
||||||
|
std::multimap<std::type_index, std::string> unhandled;
|
||||||
|
|
||||||
|
bool has(const std::string &name) const;
|
||||||
|
template<class T> const T &get(const std::string &name) const;
|
||||||
|
template<class T> T &get(const std::string &name);
|
||||||
|
template<class T = uint8_t> const T *ptr(const std::string &name) const;
|
||||||
|
template<class T = uint8_t> T *ptr(const std::string &name);
|
||||||
|
|
||||||
|
mod(const filesystem::path &, const load_mode::type &);
|
||||||
|
~mod() noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
mod::mod(const filesystem::path &path,
|
||||||
|
const load_mode::type &type)
|
||||||
|
try
|
||||||
|
:handle
|
||||||
|
{
|
||||||
|
path, type
|
||||||
|
}
|
||||||
|
,header
|
||||||
|
{
|
||||||
|
&handle.get<mapi::header>(mapi::header::sym_name)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if(unlikely(!header))
|
||||||
|
throw error("Unexpected null header");
|
||||||
|
|
||||||
|
if(header->magic != mapi::header::MAGIC)
|
||||||
|
throw error("Bad magic [%04x] need: [%04x]",
|
||||||
|
header->magic,
|
||||||
|
mapi::header::MAGIC);
|
||||||
|
}
|
||||||
|
catch(const boost::system::system_error &e)
|
||||||
|
{
|
||||||
|
throw error("%s", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
mod::~mod()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T *
|
||||||
|
mod::ptr(const std::string &name)
|
||||||
|
{
|
||||||
|
return &handle.get<T>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
const T *
|
||||||
|
mod::ptr(const std::string &name)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return &handle.get<T>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T &
|
||||||
|
mod::get(const std::string &name)
|
||||||
|
{
|
||||||
|
handle.get<T>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
const T &
|
||||||
|
mod::get(const std::string &name)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
handle.get<T>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
mod::has(const std::string &name)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return handle.has(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
name(const mod &mod)
|
||||||
|
{
|
||||||
|
return mod.handle.location().filename().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
location(const mod &mod)
|
||||||
|
{
|
||||||
|
return mod.handle.location().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
const version_t &
|
||||||
|
version(const mod &mod)
|
||||||
|
{
|
||||||
|
return header(mod).version;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *const &
|
||||||
|
desc(const mod &mod)
|
||||||
|
{
|
||||||
|
return header(mod).desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapi::exports &
|
||||||
|
exports(const mod &mod)
|
||||||
|
{
|
||||||
|
return header(mod).exports;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapi::flags &
|
||||||
|
flags(const mod &mod)
|
||||||
|
{
|
||||||
|
return header(mod).flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapi::header &
|
||||||
|
header(const mod &mod)
|
||||||
|
{
|
||||||
|
if(unlikely(!mod.header))
|
||||||
|
throw error("Header unavailable");
|
||||||
|
|
||||||
|
return *mod.header;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *
|
||||||
|
ptr(mod &mod,
|
||||||
|
const std::string &name)
|
||||||
|
{
|
||||||
|
return mod.ptr<uint8_t>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *
|
||||||
|
ptr(const mod &mod,
|
||||||
|
const std::string &name)
|
||||||
|
{
|
||||||
|
return mod.ptr<uint8_t>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
has(const mod &mod,
|
||||||
|
const std::string &name)
|
||||||
|
{
|
||||||
|
return mod.has(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mods
|
||||||
|
} // namespace ircd
|
||||||
|
#endif // __cplusplus
|
955
ircd/modules.cc
955
ircd/modules.cc
File diff suppressed because it is too large
Load diff
|
@ -276,20 +276,17 @@ conf_set_serverinfo_nicklen(void *data)
|
||||||
static void
|
static void
|
||||||
conf_set_modules_module(void *data)
|
conf_set_modules_module(void *data)
|
||||||
{
|
{
|
||||||
char *m_bn;
|
char *const m_bn = rb_basename((char *) data);
|
||||||
|
const scope free([&m_bn] { rb_free(m_bn); });
|
||||||
|
|
||||||
m_bn = rb_basename((char *) data);
|
if(!mods::loaded(m_bn))
|
||||||
|
mods::load((const char *)data);
|
||||||
if(findmodule_byname(m_bn) == NULL)
|
|
||||||
load_one_module((char *) data, MAPI_ORIGIN_EXTENSION, false);
|
|
||||||
|
|
||||||
rb_free(m_bn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
conf_set_modules_path(void *data)
|
conf_set_modules_path(void *data)
|
||||||
{
|
{
|
||||||
mod_add_path((char *) data);
|
mods::path_add((char *) data, std::nothrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mode_table_
|
struct mode_table_
|
||||||
|
|
|
@ -23,6 +23,23 @@
|
||||||
* USA
|
* USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
make_index<Message>(),
|
||||||
|
{
|
||||||
|
[](mod &mod, const std::string &name)
|
||||||
|
{
|
||||||
|
auto &tab(get<Message>(mod, name));
|
||||||
|
mod_add_cmd(&tab);
|
||||||
|
},
|
||||||
|
[](mod &mod, const std::string &name)
|
||||||
|
{
|
||||||
|
auto &tab(get<Message>(mod, name));
|
||||||
|
mod_del_cmd(&tab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace ircd {
|
namespace ircd {
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<alias_entry>, case_insensitive_less> alias_dict;
|
std::map<std::string, std::shared_ptr<alias_entry>, case_insensitive_less> alias_dict;
|
||||||
|
|
|
@ -1398,9 +1398,8 @@ clear_out_old_conf(void)
|
||||||
clear_s_newconf();
|
clear_s_newconf();
|
||||||
|
|
||||||
/* clean out module paths */
|
/* clean out module paths */
|
||||||
mod_clear_paths();
|
mods::path_clear();
|
||||||
mod_add_path(fs::MODULE_DIR);
|
mods::path_add(fs::MODPATH);
|
||||||
mod_add_path(fs::AUTOMODPATH);
|
|
||||||
|
|
||||||
/* clean out ServerInfo */
|
/* clean out ServerInfo */
|
||||||
rb_free(ServerInfo.description);
|
rb_free(ServerInfo.description);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
AUTOMAKE_OPTIONS = subdir-objects
|
moduledir=@moduledir@
|
||||||
auto_load_moddir=@moduledir@/autoload
|
|
||||||
|
|
||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
$(LTDLINCL) \
|
$(LTDLINCL) \
|
||||||
@BOOST_CPPFLAGS@ \
|
@BOOST_CPPFLAGS@ \
|
||||||
-include $(top_srcdir)/include/ircd/ircd.h
|
-include $(top_srcdir)/include/ircd/ircd.h \
|
||||||
|
-include $(top_srcdir)/include/ircd/mapi.h
|
||||||
|
|
||||||
AM_LDFLAGS = \
|
AM_LDFLAGS = \
|
||||||
-L$(top_srcdir)/ircd \
|
-L$(top_srcdir)/ircd \
|
||||||
|
@ -18,8 +18,9 @@ AM_LDFLAGS += \
|
||||||
-export-dynamic \
|
-export-dynamic \
|
||||||
-avoid-version \
|
-avoid-version \
|
||||||
-no-undefined \
|
-no-undefined \
|
||||||
--no-allow-shlib-undefined \
|
--no-allow-shlib-undefined
|
||||||
-export-symbols-regex _mheader
|
# -export-symbols-regex IRCD_MODULE*
|
||||||
|
# -export-symbols-regex *
|
||||||
|
|
||||||
AM_LDFLAGS += \
|
AM_LDFLAGS += \
|
||||||
-lircd \
|
-lircd \
|
||||||
|
@ -27,181 +28,171 @@ AM_LDFLAGS += \
|
||||||
@LIBLTDL@ \
|
@LIBLTDL@ \
|
||||||
@BOOST_LIBS@
|
@BOOST_LIBS@
|
||||||
|
|
||||||
|
#m_ban_la_SOURCES = m_ban.cc
|
||||||
cap_account_tag_la_SOURCES = cap_account_tag.cc
|
#m_die_la_SOURCES = m_die.cc
|
||||||
cap_server_time_la_SOURCES = cap_server_time.cc
|
#m_error_la_SOURCES = m_error.cc
|
||||||
chm_nocolour_la_SOURCES = chm_nocolour.cc
|
#m_join_la_SOURCES = m_join.cc
|
||||||
chm_noctcp_la_SOURCES = chm_noctcp.cc
|
#m_kick_la_SOURCES = m_kick.cc
|
||||||
m_accept_la_SOURCES = m_accept.cc
|
#m_kill_la_SOURCES = m_kill.cc
|
||||||
m_admin_la_SOURCES = m_admin.cc
|
#m_message_la_SOURCES = m_message.cc
|
||||||
m_alias_la_SOURCES = m_alias.cc
|
#m_mode_la_SOURCES = m_mode.cc
|
||||||
m_away_la_SOURCES = m_away.cc
|
m_modules_la_SOURCES = m_modules.cc
|
||||||
m_cap_la_SOURCES = m_cap.cc
|
#m_nick_la_SOURCES = m_nick.cc
|
||||||
m_capab_la_SOURCES = m_capab.cc
|
#m_part_la_SOURCES = m_part.cc
|
||||||
m_certfp_la_SOURCES = m_certfp.cc
|
#m_quit_la_SOURCES = m_quit.cc
|
||||||
m_challenge_la_SOURCES = m_challenge.cc
|
#m_server_la_SOURCES = m_server.cc
|
||||||
m_chghost_la_SOURCES = m_chghost.cc
|
#m_squit_la_SOURCES = m_squit.cc
|
||||||
m_close_la_SOURCES = m_close.cc
|
#cap_account_tag_la_SOURCES = cap_account_tag.cc
|
||||||
m_connect_la_SOURCES = m_connect.cc
|
#cap_server_time_la_SOURCES = cap_server_time.cc
|
||||||
m_dline_la_SOURCES = m_dline.cc
|
#chm_nocolour_la_SOURCES = chm_nocolour.cc
|
||||||
m_encap_la_SOURCES = m_encap.cc
|
#chm_noctcp_la_SOURCES = chm_noctcp.cc
|
||||||
m_etrace_la_SOURCES = m_etrace.cc
|
#m_accept_la_SOURCES = m_accept.cc
|
||||||
m_grant_la_SOURCES = m_grant.cc
|
#m_admin_la_SOURCES = m_admin.cc
|
||||||
m_help_la_SOURCES = m_help.cc
|
#m_alias_la_SOURCES = m_alias.cc
|
||||||
m_info_la_SOURCES = m_info.cc
|
#m_away_la_SOURCES = m_away.cc
|
||||||
m_invite_la_SOURCES = m_invite.cc
|
#m_cap_la_SOURCES = m_cap.cc
|
||||||
m_ison_la_SOURCES = m_ison.cc
|
#m_capab_la_SOURCES = m_capab.cc
|
||||||
m_kline_la_SOURCES = m_kline.cc
|
#m_certfp_la_SOURCES = m_certfp.cc
|
||||||
m_knock_la_SOURCES = m_knock.cc
|
#m_challenge_la_SOURCES = m_challenge.cc
|
||||||
m_links_la_SOURCES = m_links.cc
|
#m_chghost_la_SOURCES = m_chghost.cc
|
||||||
m_list_la_SOURCES = m_list.cc
|
#m_close_la_SOURCES = m_close.cc
|
||||||
m_lusers_la_SOURCES = m_lusers.cc
|
#m_connect_la_SOURCES = m_connect.cc
|
||||||
m_map_la_SOURCES = m_map.cc
|
#m_dline_la_SOURCES = m_dline.cc
|
||||||
m_monitor_la_SOURCES = m_monitor.cc
|
#m_encap_la_SOURCES = m_encap.cc
|
||||||
m_motd_la_SOURCES = m_motd.cc
|
#m_etrace_la_SOURCES = m_etrace.cc
|
||||||
m_names_la_SOURCES = m_names.cc
|
#m_grant_la_SOURCES = m_grant.cc
|
||||||
m_oper_la_SOURCES = m_oper.cc
|
#m_help_la_SOURCES = m_help.cc
|
||||||
m_operspy_la_SOURCES = m_operspy.cc
|
#m_info_la_SOURCES = m_info.cc
|
||||||
m_pass_la_SOURCES = m_pass.cc
|
#m_invite_la_SOURCES = m_invite.cc
|
||||||
m_ping_la_SOURCES = m_ping.cc
|
#m_ison_la_SOURCES = m_ison.cc
|
||||||
m_pong_la_SOURCES = m_pong.cc
|
#m_kline_la_SOURCES = m_kline.cc
|
||||||
m_post_la_SOURCES = m_post.cc
|
#m_knock_la_SOURCES = m_knock.cc
|
||||||
m_privs_la_SOURCES = m_privs.cc
|
#m_links_la_SOURCES = m_links.cc
|
||||||
m_rehash_la_SOURCES = m_rehash.cc
|
#m_list_la_SOURCES = m_list.cc
|
||||||
m_restart_la_SOURCES = m_restart.cc
|
#m_lusers_la_SOURCES = m_lusers.cc
|
||||||
m_resv_la_SOURCES = m_resv.cc
|
#m_map_la_SOURCES = m_map.cc
|
||||||
m_sasl_la_SOURCES = m_sasl.cc
|
#m_monitor_la_SOURCES = m_monitor.cc
|
||||||
m_scan_la_SOURCES = m_scan.cc
|
#m_motd_la_SOURCES = m_motd.cc
|
||||||
m_services_la_SOURCES = m_services.cc
|
#m_names_la_SOURCES = m_names.cc
|
||||||
m_set_la_SOURCES = m_set.cc
|
#m_oper_la_SOURCES = m_oper.cc
|
||||||
m_signon_la_SOURCES = m_signon.cc
|
#m_operspy_la_SOURCES = m_operspy.cc
|
||||||
m_snote_la_SOURCES = m_snote.cc
|
#m_pass_la_SOURCES = m_pass.cc
|
||||||
m_starttls_la_SOURCES = m_starttls.cc
|
#m_ping_la_SOURCES = m_ping.cc
|
||||||
m_stats_la_SOURCES = m_stats.cc
|
#m_pong_la_SOURCES = m_pong.cc
|
||||||
m_svinfo_la_SOURCES = m_svinfo.cc
|
#m_post_la_SOURCES = m_post.cc
|
||||||
m_tb_la_SOURCES = m_tb.cc
|
#m_privs_la_SOURCES = m_privs.cc
|
||||||
m_testline_la_SOURCES = m_testline.cc
|
#m_rehash_la_SOURCES = m_rehash.cc
|
||||||
m_testmask_la_SOURCES = m_testmask.cc
|
#m_restart_la_SOURCES = m_restart.cc
|
||||||
m_tginfo_la_SOURCES = m_tginfo.cc
|
#m_resv_la_SOURCES = m_resv.cc
|
||||||
m_time_la_SOURCES = m_time.cc
|
#m_sasl_la_SOURCES = m_sasl.cc
|
||||||
m_topic_la_SOURCES = m_topic.cc
|
#m_scan_la_SOURCES = m_scan.cc
|
||||||
m_trace_la_SOURCES = m_trace.cc
|
#m_services_la_SOURCES = m_services.cc
|
||||||
m_unreject_la_SOURCES = m_unreject.cc
|
#m_set_la_SOURCES = m_set.cc
|
||||||
m_user_la_SOURCES = m_user.cc
|
#m_signon_la_SOURCES = m_signon.cc
|
||||||
m_userhost_la_SOURCES = m_userhost.cc
|
#m_snote_la_SOURCES = m_snote.cc
|
||||||
m_users_la_SOURCES = m_users.cc
|
#m_starttls_la_SOURCES = m_starttls.cc
|
||||||
m_version_la_SOURCES = m_version.cc
|
#m_stats_la_SOURCES = m_stats.cc
|
||||||
m_wallops_la_SOURCES = m_wallops.cc
|
#m_svinfo_la_SOURCES = m_svinfo.cc
|
||||||
m_who_la_SOURCES = m_who.cc
|
#m_tb_la_SOURCES = m_tb.cc
|
||||||
m_whois_la_SOURCES = m_whois.cc
|
#m_testline_la_SOURCES = m_testline.cc
|
||||||
m_whowas_la_SOURCES = m_whowas.cc
|
#m_testmask_la_SOURCES = m_testmask.cc
|
||||||
m_xline_la_SOURCES = m_xline.cc
|
#m_tginfo_la_SOURCES = m_tginfo.cc
|
||||||
sno_routing_la_SOURCES = sno_routing.cc
|
#m_time_la_SOURCES = m_time.cc
|
||||||
|
#m_topic_la_SOURCES = m_topic.cc
|
||||||
auto_load_mod_LTLIBRARIES = \
|
#m_trace_la_SOURCES = m_trace.cc
|
||||||
cap_account_tag.la \
|
#m_unreject_la_SOURCES = m_unreject.cc
|
||||||
cap_server_time.la \
|
#m_user_la_SOURCES = m_user.cc
|
||||||
chm_nocolour.la \
|
#m_userhost_la_SOURCES = m_userhost.cc
|
||||||
chm_noctcp.la \
|
#m_users_la_SOURCES = m_users.cc
|
||||||
m_accept.la \
|
#m_version_la_SOURCES = m_version.cc
|
||||||
m_admin.la \
|
#m_wallops_la_SOURCES = m_wallops.cc
|
||||||
m_alias.la \
|
#m_who_la_SOURCES = m_who.cc
|
||||||
m_away.la \
|
#m_whois_la_SOURCES = m_whois.cc
|
||||||
m_cap.la \
|
#m_whowas_la_SOURCES = m_whowas.cc
|
||||||
m_capab.la \
|
#m_xline_la_SOURCES = m_xline.cc
|
||||||
m_certfp.la \
|
#sno_routing_la_SOURCES = sno_routing.cc
|
||||||
m_challenge.la \
|
|
||||||
m_chghost.la \
|
|
||||||
m_close.la \
|
|
||||||
m_connect.la \
|
|
||||||
m_dline.la \
|
|
||||||
m_encap.la \
|
|
||||||
m_etrace.la \
|
|
||||||
m_grant.la \
|
|
||||||
m_help.la \
|
|
||||||
m_info.la \
|
|
||||||
m_invite.la \
|
|
||||||
m_ison.la \
|
|
||||||
m_kline.la \
|
|
||||||
m_knock.la \
|
|
||||||
m_links.la \
|
|
||||||
m_list.la \
|
|
||||||
m_lusers.la \
|
|
||||||
m_map.la \
|
|
||||||
m_monitor.la \
|
|
||||||
m_motd.la \
|
|
||||||
m_names.la \
|
|
||||||
m_oper.la \
|
|
||||||
m_operspy.la \
|
|
||||||
m_pass.la \
|
|
||||||
m_ping.la \
|
|
||||||
m_pong.la \
|
|
||||||
m_post.la \
|
|
||||||
m_privs.la \
|
|
||||||
m_rehash.la \
|
|
||||||
m_restart.la \
|
|
||||||
m_resv.la \
|
|
||||||
m_sasl.la \
|
|
||||||
m_scan.la \
|
|
||||||
m_services.la \
|
|
||||||
m_set.la \
|
|
||||||
m_signon.la \
|
|
||||||
m_snote.la \
|
|
||||||
m_starttls.la \
|
|
||||||
m_stats.la \
|
|
||||||
m_svinfo.la \
|
|
||||||
m_tb.la \
|
|
||||||
m_testline.la \
|
|
||||||
m_testmask.la \
|
|
||||||
m_tginfo.la \
|
|
||||||
m_time.la \
|
|
||||||
m_topic.la \
|
|
||||||
m_trace.la \
|
|
||||||
m_unreject.la \
|
|
||||||
m_user.la \
|
|
||||||
m_userhost.la \
|
|
||||||
m_users.la \
|
|
||||||
m_version.la \
|
|
||||||
m_wallops.la \
|
|
||||||
m_who.la \
|
|
||||||
m_whois.la \
|
|
||||||
m_whowas.la \
|
|
||||||
m_xline.la \
|
|
||||||
sno_routing.la
|
|
||||||
|
|
||||||
|
|
||||||
core_m_ban_la_SOURCES = core/m_ban.cc
|
|
||||||
core_m_die_la_SOURCES = core/m_die.cc
|
|
||||||
core_m_error_la_SOURCES = core/m_error.cc
|
|
||||||
core_m_join_la_SOURCES = core/m_join.cc
|
|
||||||
core_m_kick_la_SOURCES = core/m_kick.cc
|
|
||||||
core_m_kill_la_SOURCES = core/m_kill.cc
|
|
||||||
core_m_message_la_SOURCES = core/m_message.cc
|
|
||||||
core_m_mode_la_SOURCES = core/m_mode.cc
|
|
||||||
core_m_modules_la_SOURCES = core/m_modules.cc
|
|
||||||
core_m_nick_la_SOURCES = core/m_nick.cc
|
|
||||||
core_m_part_la_SOURCES = core/m_part.cc
|
|
||||||
core_m_quit_la_SOURCES = core/m_quit.cc
|
|
||||||
core_m_server_la_SOURCES = core/m_server.cc
|
|
||||||
core_m_squit_la_SOURCES = core/m_squit.cc
|
|
||||||
|
|
||||||
module_LTLIBRARIES = \
|
module_LTLIBRARIES = \
|
||||||
core/m_ban.la \
|
m_modules.la
|
||||||
core/m_die.la \
|
# m_ban.la \
|
||||||
core/m_error.la \
|
# m_die.la \
|
||||||
core/m_join.la \
|
# m_error.la \
|
||||||
core/m_kick.la \
|
# m_join.la \
|
||||||
core/m_kill.la \
|
# m_kick.la \
|
||||||
core/m_message.la \
|
# m_kill.la \
|
||||||
core/m_mode.la \
|
# m_message.la \
|
||||||
core/m_modules.la \
|
# m_mode.la \
|
||||||
core/m_nick.la \
|
# m_nick.la \
|
||||||
core/m_part.la \
|
# m_part.la \
|
||||||
core/m_quit.la \
|
# m_quit.la \
|
||||||
core/m_server.la \
|
# m_server.la \
|
||||||
core/m_squit.la
|
# m_squit.la \
|
||||||
|
# cap_account_tag.la \
|
||||||
|
# cap_server_time.la \
|
||||||
mrproper-local:
|
# chm_nocolour.la \
|
||||||
rm -rf core/.deps
|
# chm_noctcp.la \
|
||||||
rm -f core/.dirstamp
|
# m_accept.la \
|
||||||
|
# m_admin.la \
|
||||||
|
# m_alias.la \
|
||||||
|
# m_away.la \
|
||||||
|
# m_cap.la \
|
||||||
|
# m_capab.la \
|
||||||
|
# m_certfp.la \
|
||||||
|
# m_challenge.la \
|
||||||
|
# m_chghost.la \
|
||||||
|
# m_close.la \
|
||||||
|
# m_connect.la \
|
||||||
|
# m_dline.la \
|
||||||
|
# m_encap.la \
|
||||||
|
# m_etrace.la \
|
||||||
|
# m_grant.la \
|
||||||
|
# m_help.la \
|
||||||
|
# m_info.la \
|
||||||
|
# m_invite.la \
|
||||||
|
# m_ison.la \
|
||||||
|
# m_kline.la \
|
||||||
|
# m_knock.la \
|
||||||
|
# m_links.la \
|
||||||
|
# m_list.la \
|
||||||
|
# m_lusers.la \
|
||||||
|
# m_map.la \
|
||||||
|
# m_monitor.la \
|
||||||
|
# m_motd.la \
|
||||||
|
# m_names.la \
|
||||||
|
# m_oper.la \
|
||||||
|
# m_operspy.la \
|
||||||
|
# m_pass.la \
|
||||||
|
# m_ping.la \
|
||||||
|
# m_pong.la \
|
||||||
|
# m_post.la \
|
||||||
|
# m_privs.la \
|
||||||
|
# m_rehash.la \
|
||||||
|
# m_restart.la \
|
||||||
|
# m_resv.la \
|
||||||
|
# m_sasl.la \
|
||||||
|
# m_scan.la \
|
||||||
|
# m_services.la \
|
||||||
|
# m_set.la \
|
||||||
|
# m_signon.la \
|
||||||
|
# m_snote.la \
|
||||||
|
# m_starttls.la \
|
||||||
|
# m_stats.la \
|
||||||
|
# m_svinfo.la \
|
||||||
|
# m_tb.la \
|
||||||
|
# m_testline.la \
|
||||||
|
# m_testmask.la \
|
||||||
|
# m_tginfo.la \
|
||||||
|
# m_time.la \
|
||||||
|
# m_topic.la \
|
||||||
|
# m_trace.la \
|
||||||
|
# m_unreject.la \
|
||||||
|
# m_user.la \
|
||||||
|
# m_userhost.la \
|
||||||
|
# m_users.la \
|
||||||
|
# m_version.la \
|
||||||
|
# m_wallops.la \
|
||||||
|
# m_who.la \
|
||||||
|
# m_whois.la \
|
||||||
|
# m_whowas.la \
|
||||||
|
# m_xline.la \
|
||||||
|
# sno_routing.la
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
/* modules/m_modules.c - module for module loading
|
/* modules/m_modules.c - module for module loading
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Charybdis Development Team
|
||||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
||||||
|
* Copyright (c) 2016 Jason Volk <jason@zemos.net>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -20,8 +23,6 @@
|
||||||
|
|
||||||
using namespace ircd;
|
using namespace ircd;
|
||||||
|
|
||||||
static const char modules_desc[] = "Provides module management commands";
|
|
||||||
|
|
||||||
static void m_modlist(struct MsgBuf *, client::client &, client::client &, int, const char **);
|
static void m_modlist(struct MsgBuf *, client::client &, client::client &, int, const char **);
|
||||||
|
|
||||||
static void mo_modload(struct MsgBuf *, client::client &, client::client &, int, const char **);
|
static void mo_modload(struct MsgBuf *, client::client &, client::client &, int, const char **);
|
||||||
|
@ -35,10 +36,10 @@ static void me_modreload(struct MsgBuf *, client::client &, client::client &, in
|
||||||
static void me_modunload(struct MsgBuf *, client::client &, client::client &, int, const char **);
|
static void me_modunload(struct MsgBuf *, client::client &, client::client &, int, const char **);
|
||||||
static void me_modrestart(struct MsgBuf *, client::client &, client::client &, int, const char **);
|
static void me_modrestart(struct MsgBuf *, client::client &, client::client &, int, const char **);
|
||||||
|
|
||||||
static void do_modload(client::client &, const char *);
|
static void do_modload(client::client &, const std::string &);
|
||||||
static void do_modunload(client::client &, const char *);
|
static void do_modunload(client::client &, const std::string &);
|
||||||
static void do_modreload(client::client &, const char *);
|
static void do_modreload(client::client &, const std::string &);
|
||||||
static void do_modlist(client::client &, const char *);
|
static void do_modlist(client::client &, const std::string &);
|
||||||
static void do_modrestart(client::client &);
|
static void do_modrestart(client::client &);
|
||||||
|
|
||||||
struct Message modload_msgtab = {
|
struct Message modload_msgtab = {
|
||||||
|
@ -66,11 +67,19 @@ struct Message modrestart_msgtab = {
|
||||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modrestart, 0}, {mo_modrestart, 0}}
|
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modrestart, 0}, {mo_modrestart, 0}}
|
||||||
};
|
};
|
||||||
|
|
||||||
mapi_clist_av1 modules_clist[] = { &modload_msgtab, &modunload_msgtab, &modreload_msgtab, &modlist_msgtab, &modrestart_msgtab, NULL };
|
|
||||||
|
|
||||||
DECLARE_MODULE_AV2(modules, NULL, NULL, modules_clist, NULL, NULL, NULL, NULL, modules_desc);
|
mapi::header IRCD_MODULE
|
||||||
|
{
|
||||||
|
"Provides module management commands",
|
||||||
|
mapi::NO_FLAGS,
|
||||||
|
&modload_msgtab,
|
||||||
|
&modunload_msgtab,
|
||||||
|
&modreload_msgtab,
|
||||||
|
&modlist_msgtab,
|
||||||
|
&modrestart_msgtab,
|
||||||
|
};
|
||||||
|
|
||||||
/* load a module .. */
|
// load a module ..
|
||||||
static void
|
static void
|
||||||
mo_modload(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv)
|
mo_modload(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv)
|
||||||
{
|
{
|
||||||
|
@ -106,7 +115,7 @@ me_modload(struct MsgBuf *msgbuf_p, client::client &client, client::client &sour
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* unload a module .. */
|
// unload a module ..
|
||||||
static void
|
static void
|
||||||
mo_modunload(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv)
|
mo_modunload(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv)
|
||||||
{
|
{
|
||||||
|
@ -141,7 +150,7 @@ me_modunload(struct MsgBuf *msgbuf_p, client::client &client, client::client &so
|
||||||
do_modunload(source, parv[1]);
|
do_modunload(source, parv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unload and load in one! */
|
// unload and load in one!
|
||||||
static void
|
static void
|
||||||
mo_modreload(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv)
|
mo_modreload(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv)
|
||||||
{
|
{
|
||||||
|
@ -176,7 +185,7 @@ me_modreload(struct MsgBuf *msgbuf_p, client::client &client, client::client &so
|
||||||
do_modreload(source, parv[1]);
|
do_modreload(source, parv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* list modules .. */
|
// list modules ..
|
||||||
static void
|
static void
|
||||||
m_modlist(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv)
|
m_modlist(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv)
|
||||||
{
|
{
|
||||||
|
@ -197,7 +206,7 @@ me_modlist(struct MsgBuf *msgbuf_p, client::client &client, client::client &sour
|
||||||
do_modlist(source, parv[1]);
|
do_modlist(source, parv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unload and reload all modules */
|
// unload and reload all modules
|
||||||
static void
|
static void
|
||||||
mo_modrestart(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv)
|
mo_modrestart(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv)
|
||||||
{
|
{
|
||||||
|
@ -233,87 +242,46 @@ me_modrestart(struct MsgBuf *msgbuf_p, client::client &client, client::client &s
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_modload(client::client &source, const char *module)
|
do_modload(client::client &source,
|
||||||
|
const std::string &name)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
char *m_bn = rb_basename(module);
|
mods::load(name);
|
||||||
int origin;
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
if(findmodule_byname(m_bn) != NULL)
|
{
|
||||||
{
|
sendto_one_notice(&source, "%s", e.what());
|
||||||
sendto_one_notice(&source, ":Module %s is already loaded", m_bn);
|
|
||||||
rb_free(m_bn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
origin = strcmp(module, m_bn) == 0 ? MAPI_ORIGIN_CORE : MAPI_ORIGIN_EXTENSION;
|
|
||||||
load_one_module(module, origin, false);
|
|
||||||
|
|
||||||
rb_free(m_bn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_modunload(client::client &source, const char *module)
|
do_modunload(client::client &source,
|
||||||
|
const std::string &name)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
struct module *mod;
|
if(!mods::loaded(name))
|
||||||
char *m_bn = rb_basename(module);
|
|
||||||
|
|
||||||
if((mod = findmodule_byname(m_bn)) == NULL)
|
|
||||||
{
|
{
|
||||||
sendto_one_notice(&source, ":Module %s is not loaded", m_bn);
|
sendto_one_notice(&source, ":%s is not loaded", name.c_str());
|
||||||
rb_free(m_bn);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mod->core)
|
mods::unload(name);
|
||||||
{
|
}
|
||||||
sendto_one_notice(&source, ":Module %s is a core module and may not be unloaded", m_bn);
|
catch(const std::exception &e)
|
||||||
rb_free(m_bn);
|
{
|
||||||
return;
|
sendto_one_notice(&source, "%s", e.what());
|
||||||
}
|
|
||||||
|
|
||||||
if(unload_one_module(m_bn, true) == false)
|
|
||||||
sendto_one_notice(&source, ":Module %s is not loaded", m_bn);
|
|
||||||
|
|
||||||
rb_free(m_bn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_modreload(client::client &source, const char *module)
|
do_modreload(client::client &source,
|
||||||
|
const std::string &name)
|
||||||
{
|
{
|
||||||
struct module *mod;
|
|
||||||
int check_core;
|
|
||||||
char *m_bn = rb_basename(module);
|
|
||||||
|
|
||||||
if((mod = findmodule_byname(m_bn)) == NULL)
|
|
||||||
{
|
|
||||||
sendto_one_notice(&source, ":Module %s is not loaded", m_bn);
|
|
||||||
rb_free(m_bn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
check_core = mod->core;
|
|
||||||
|
|
||||||
if(unload_one_module(m_bn, true) == false)
|
|
||||||
{
|
|
||||||
sendto_one_notice(&source, ":Module %s is not loaded", m_bn);
|
|
||||||
rb_free(m_bn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((load_one_module(m_bn, mod->origin, check_core) == false) && check_core)
|
|
||||||
{
|
|
||||||
sendto_realops_snomask(sno::GENERAL, L_NETWIDE,
|
|
||||||
"Error reloading core module: %s: terminating ircd", m_bn);
|
|
||||||
ilog(L_MAIN, "Error loading core module %s: terminating ircd", m_bn);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
rb_free(m_bn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_modrestart(client::client &source)
|
do_modrestart(client::client &source)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
unsigned int modnum = 0;
|
unsigned int modnum = 0;
|
||||||
rb_dlink_node *ptr, *nptr;
|
rb_dlink_node *ptr, *nptr;
|
||||||
|
|
||||||
|
@ -339,65 +307,36 @@ do_modrestart(client::client &source)
|
||||||
}
|
}
|
||||||
|
|
||||||
load_all_modules(false);
|
load_all_modules(false);
|
||||||
load_core_modules(false);
|
|
||||||
rehash(false);
|
rehash(false);
|
||||||
|
|
||||||
sendto_realops_snomask(sno::GENERAL, L_NETWIDE,
|
sendto_realops_snomask(sno::GENERAL, L_NETWIDE,
|
||||||
"Module Restart: %u modules unloaded, %lu modules loaded",
|
"Module Restart: %u modules unloaded, %lu modules loaded",
|
||||||
modnum, rb_dlink_list_length(&module_list));
|
modnum, rb_dlink_list_length(&module_list));
|
||||||
ilog(L_MAIN, "Module Restart: %u modules unloaded, %lu modules loaded", modnum, rb_dlink_list_length(&module_list));
|
ilog(L_MAIN, "Module Restart: %u modules unloaded, %lu modules loaded", modnum, rb_dlink_list_length(&module_list));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_modlist(client::client &source, const char *pattern)
|
do_modlist(client::client &source, const std::string &pattern)
|
||||||
{
|
{
|
||||||
rb_dlink_node *ptr;
|
for(const auto &pit : mods::loaded())
|
||||||
int i;
|
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, module_list.head)
|
|
||||||
{
|
{
|
||||||
struct module *mod = (module *)ptr->data;
|
const auto &mod(*pit.second);
|
||||||
bool display = false;
|
if(pattern.empty() || match(pattern, name(mod)))
|
||||||
const char *origin;
|
|
||||||
|
|
||||||
switch (mod->origin)
|
|
||||||
{
|
|
||||||
case MAPI_ORIGIN_EXTENSION:
|
|
||||||
origin = "extension";
|
|
||||||
display = true;
|
|
||||||
break;
|
|
||||||
case MAPI_ORIGIN_CORE:
|
|
||||||
origin = "builtin";
|
|
||||||
display = is(source, umode::OPER);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
origin = "unknown";
|
|
||||||
display = is(source, umode::OPER);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!display)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(pattern)
|
|
||||||
{
|
|
||||||
if(match(pattern, mod->name))
|
|
||||||
{
|
|
||||||
sendto_one(&source, form_str(RPL_MODLIST),
|
|
||||||
me.name, source.name,
|
|
||||||
mod->name,
|
|
||||||
(unsigned long)(uintptr_t)mod->address, origin,
|
|
||||||
mod->core ? " (core)" : "", mod->version, mod->description);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
sendto_one(&source, form_str(RPL_MODLIST),
|
sendto_one(&source, form_str(RPL_MODLIST),
|
||||||
me.name, source.name, mod->name,
|
me.name,
|
||||||
(unsigned long)(uintptr_t)mod->address, origin,
|
source.name,
|
||||||
mod->core ? " (core)" : "", mod->version, mod->description);
|
name(mod).c_str(),
|
||||||
|
ulong(0),
|
||||||
|
"*",
|
||||||
|
"*",
|
||||||
|
"*", //version(mod),
|
||||||
|
desc(mod));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendto_one(&source, form_str(RPL_ENDOFMODLIST), me.name, source.name);
|
sendto_one(&source, form_str(RPL_ENDOFMODLIST),
|
||||||
|
me.name,
|
||||||
|
source.name);
|
||||||
}
|
}
|
Loading…
Reference in a new issue