ircd: implement support for remote module load/unload/etc commands
This commit is contained in:
parent
cc7ae51cdc
commit
15feac531c
4 changed files with 188 additions and 63 deletions
|
@ -673,6 +673,7 @@ shared {
|
||||||
* undline - allow removing dlines
|
* undline - allow removing dlines
|
||||||
* grant - allow granting operator status
|
* grant - allow granting operator status
|
||||||
* die - allow remote DIE/RESTART
|
* die - allow remote DIE/RESTART
|
||||||
|
* module - allow remote module commands
|
||||||
* none - disallow everything
|
* none - disallow everything
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -82,22 +82,23 @@ struct remote_conf
|
||||||
};
|
};
|
||||||
|
|
||||||
/* flags used in shared/cluster */
|
/* flags used in shared/cluster */
|
||||||
#define SHARED_TKLINE 0x0001
|
#define SHARED_TKLINE 0x00001
|
||||||
#define SHARED_PKLINE 0x0002
|
#define SHARED_PKLINE 0x00002
|
||||||
#define SHARED_UNKLINE 0x0004
|
#define SHARED_UNKLINE 0x00004
|
||||||
#define SHARED_LOCOPS 0x0008
|
#define SHARED_LOCOPS 0x00008
|
||||||
#define SHARED_TXLINE 0x0010
|
#define SHARED_TXLINE 0x00010
|
||||||
#define SHARED_PXLINE 0x0020
|
#define SHARED_PXLINE 0x00020
|
||||||
#define SHARED_UNXLINE 0x0040
|
#define SHARED_UNXLINE 0x00040
|
||||||
#define SHARED_TRESV 0x0080
|
#define SHARED_TRESV 0x00080
|
||||||
#define SHARED_PRESV 0x0100
|
#define SHARED_PRESV 0x00100
|
||||||
#define SHARED_UNRESV 0x0200
|
#define SHARED_UNRESV 0x00200
|
||||||
#define SHARED_REHASH 0x0400
|
#define SHARED_REHASH 0x00400
|
||||||
#define SHARED_TDLINE 0x0800
|
#define SHARED_TDLINE 0x00800
|
||||||
#define SHARED_PDLINE 0x1000
|
#define SHARED_PDLINE 0x01000
|
||||||
#define SHARED_UNDLINE 0x2000
|
#define SHARED_UNDLINE 0x02000
|
||||||
#define SHARED_GRANT 0x4000
|
#define SHARED_GRANT 0x04000
|
||||||
#define SHARED_DIE 0x8000
|
#define SHARED_DIE 0x08000
|
||||||
|
#define SHARED_MODULE 0x10000
|
||||||
|
|
||||||
#define SHARED_ALL (SHARED_TKLINE | SHARED_PKLINE | SHARED_UNKLINE |\
|
#define SHARED_ALL (SHARED_TKLINE | SHARED_PKLINE | SHARED_UNKLINE |\
|
||||||
SHARED_PXLINE | SHARED_TXLINE | SHARED_UNXLINE |\
|
SHARED_PXLINE | SHARED_TXLINE | SHARED_UNXLINE |\
|
||||||
|
|
216
ircd/modules.c
216
ircd/modules.c
|
@ -25,8 +25,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stdinc.h"
|
#include "stdinc.h"
|
||||||
|
|
||||||
|
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "ircd.h"
|
#include "ircd.h"
|
||||||
|
@ -38,7 +36,7 @@
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "ircd_defs.h"
|
#include "ircd_defs.h"
|
||||||
#include "match.h"
|
#include "match.h"
|
||||||
|
#include "s_serv.h"
|
||||||
|
|
||||||
#include <ltdl.h>
|
#include <ltdl.h>
|
||||||
|
|
||||||
|
@ -73,29 +71,41 @@ static int mo_modreload(struct Client *, struct Client *, int, const char **);
|
||||||
static int mo_modunload(struct Client *, struct Client *, int, const char **);
|
static int mo_modunload(struct Client *, struct Client *, int, const char **);
|
||||||
static int mo_modrestart(struct Client *, struct Client *, int, const char **);
|
static int mo_modrestart(struct Client *, struct Client *, int, const char **);
|
||||||
|
|
||||||
|
static int me_modload(struct Client *, struct Client *, int, const char **);
|
||||||
|
static int me_modlist(struct Client *, struct Client *, int, const char **);
|
||||||
|
static int me_modreload(struct Client *, struct Client *, int, const char **);
|
||||||
|
static int me_modunload(struct Client *, struct Client *, int, const char **);
|
||||||
|
static int me_modrestart(struct Client *, struct Client *, int, const char **);
|
||||||
|
|
||||||
|
static int do_modload(struct Client *, const char *);
|
||||||
|
static int do_modunload(struct Client *, const char *);
|
||||||
|
static int do_modreload(struct Client *, const char *);
|
||||||
|
static int do_modlist(struct Client *, const char *);
|
||||||
|
static int do_modrestart(struct Client *);
|
||||||
|
|
||||||
struct Message modload_msgtab = {
|
struct Message modload_msgtab = {
|
||||||
"MODLOAD", 0, 0, 0, MFLG_SLOW,
|
"MODLOAD", 0, 0, 0, MFLG_SLOW,
|
||||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modload, 2}}
|
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modload, 2}, {mo_modload, 2}}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Message modunload_msgtab = {
|
struct Message modunload_msgtab = {
|
||||||
"MODUNLOAD", 0, 0, 0, MFLG_SLOW,
|
"MODUNLOAD", 0, 0, 0, MFLG_SLOW,
|
||||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modunload, 2}}
|
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modunload, 2}, {mo_modunload, 2}}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Message modreload_msgtab = {
|
struct Message modreload_msgtab = {
|
||||||
"MODRELOAD", 0, 0, 0, MFLG_SLOW,
|
"MODRELOAD", 0, 0, 0, MFLG_SLOW,
|
||||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modreload, 2}}
|
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modreload, 2}, {mo_modreload, 2}}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Message modlist_msgtab = {
|
struct Message modlist_msgtab = {
|
||||||
"MODLIST", 0, 0, 0, MFLG_SLOW,
|
"MODLIST", 0, 0, 0, MFLG_SLOW,
|
||||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modlist, 0}}
|
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modlist, 0}, {mo_modlist, 0}}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Message modrestart_msgtab = {
|
struct Message modrestart_msgtab = {
|
||||||
"MODRESTART", 0, 0, 0, MFLG_SLOW,
|
"MODRESTART", 0, 0, 0, MFLG_SLOW,
|
||||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modrestart, 0}}
|
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modrestart, 0}, {mo_modrestart, 0}}
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -318,8 +328,6 @@ load_one_module(const char *path, int coremodule)
|
||||||
static int
|
static int
|
||||||
mo_modload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
mo_modload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||||
{
|
{
|
||||||
char *m_bn;
|
|
||||||
|
|
||||||
if(!IsOperAdmin(source_p))
|
if(!IsOperAdmin(source_p))
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
||||||
|
@ -327,7 +335,34 @@ mo_modload(struct Client *client_p, struct Client *source_p, int parc, const cha
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bn = rb_basename(parv[1]);
|
if(parc > 2)
|
||||||
|
{
|
||||||
|
sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS,
|
||||||
|
"ENCAP %s MODLOAD %s", parv[2], parv[1]);
|
||||||
|
if (match(parv[2], me.name) == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_modload(source_p, parv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
me_modload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||||
|
{
|
||||||
|
if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
|
||||||
|
{
|
||||||
|
sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
|
||||||
|
"to load modules on this server.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_modload(source_p, parv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_modload(struct Client *source_p, const char *module)
|
||||||
|
{
|
||||||
|
char *m_bn = rb_basename(module);
|
||||||
|
|
||||||
if(findmodule_byname(m_bn) != -1)
|
if(findmodule_byname(m_bn) != -1)
|
||||||
{
|
{
|
||||||
|
@ -336,7 +371,7 @@ mo_modload(struct Client *client_p, struct Client *source_p, int parc, const cha
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
load_one_module(parv[1], 0);
|
load_one_module(module, 0);
|
||||||
|
|
||||||
rb_free(m_bn);
|
rb_free(m_bn);
|
||||||
|
|
||||||
|
@ -348,9 +383,6 @@ mo_modload(struct Client *client_p, struct Client *source_p, int parc, const cha
|
||||||
static int
|
static int
|
||||||
mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||||
{
|
{
|
||||||
char *m_bn;
|
|
||||||
int modindex;
|
|
||||||
|
|
||||||
if(!IsOperAdmin(source_p))
|
if(!IsOperAdmin(source_p))
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
||||||
|
@ -358,7 +390,35 @@ mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const c
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bn = rb_basename(parv[1]);
|
if(parc > 2)
|
||||||
|
{
|
||||||
|
sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS,
|
||||||
|
"ENCAP %s MODUNLOAD %s", parv[2], parv[1]);
|
||||||
|
if (match(parv[2], me.name) == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_modunload(source_p, parv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
me_modunload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||||
|
{
|
||||||
|
if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
|
||||||
|
{
|
||||||
|
sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
|
||||||
|
"to load modules on this server.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_modunload(source_p, parv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_modunload(struct Client *source_p, const char *module)
|
||||||
|
{
|
||||||
|
int modindex;
|
||||||
|
char *m_bn = rb_basename(module);
|
||||||
|
|
||||||
if((modindex = findmodule_byname(m_bn)) == -1)
|
if((modindex = findmodule_byname(m_bn)) == -1)
|
||||||
{
|
{
|
||||||
|
@ -387,10 +447,6 @@ mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const c
|
||||||
static int
|
static int
|
||||||
mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||||
{
|
{
|
||||||
char *m_bn;
|
|
||||||
int modindex;
|
|
||||||
int check_core;
|
|
||||||
|
|
||||||
if(!IsOperAdmin(source_p))
|
if(!IsOperAdmin(source_p))
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
||||||
|
@ -398,7 +454,36 @@ mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const c
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bn = rb_basename(parv[1]);
|
if(parc > 2)
|
||||||
|
{
|
||||||
|
sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS,
|
||||||
|
"ENCAP %s MODRELOAD %s", parv[2], parv[1]);
|
||||||
|
if (match(parv[2], me.name) == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_modreload(source_p, parv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
me_modreload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||||
|
{
|
||||||
|
if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
|
||||||
|
{
|
||||||
|
sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
|
||||||
|
"to load modules on this server.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_modreload(source_p, parv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_modreload(struct Client *source_p, const char *module)
|
||||||
|
{
|
||||||
|
int modindex;
|
||||||
|
int check_core;
|
||||||
|
char *m_bn = rb_basename(module);
|
||||||
|
|
||||||
if((modindex = findmodule_byname(m_bn)) == -1)
|
if((modindex = findmodule_byname(m_bn)) == -1)
|
||||||
{
|
{
|
||||||
|
@ -418,7 +503,7 @@ mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const c
|
||||||
|
|
||||||
if((load_one_module(m_bn, check_core) == -1) && check_core)
|
if((load_one_module(m_bn, check_core) == -1) && check_core)
|
||||||
{
|
{
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
|
||||||
"Error reloading core module: %s: terminating ircd", m_bn);
|
"Error reloading core module: %s: terminating ircd", m_bn);
|
||||||
ilog(L_MAIN, "Error loading core module %s: terminating ircd", m_bn);
|
ilog(L_MAIN, "Error loading core module %s: terminating ircd", m_bn);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -432,8 +517,6 @@ mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const c
|
||||||
static int
|
static int
|
||||||
mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
if(!IsOperAdmin(source_p))
|
if(!IsOperAdmin(source_p))
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
||||||
|
@ -441,11 +524,40 @@ mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const cha
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(parc > 2)
|
||||||
|
{
|
||||||
|
sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS,
|
||||||
|
"ENCAP %s MODLIST %s", parv[2], parv[1]);
|
||||||
|
if (match(parv[2], me.name) == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_modlist(source_p, parc > 1 ? parv[1] : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
me_modlist(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||||
|
{
|
||||||
|
if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
|
||||||
|
{
|
||||||
|
sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
|
||||||
|
"to load modules on this server.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_modlist(source_p, parv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_modlist(struct Client *source_p, const char *pattern)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < num_mods; i++)
|
for (i = 0; i < num_mods; i++)
|
||||||
{
|
{
|
||||||
if(parc > 1)
|
if(pattern)
|
||||||
{
|
{
|
||||||
if(match(parv[1], modlist[i]->name))
|
if(match(pattern, modlist[i]->name))
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(RPL_MODLIST),
|
sendto_one(source_p, form_str(RPL_MODLIST),
|
||||||
me.name, source_p->name,
|
me.name, source_p->name,
|
||||||
|
@ -458,8 +570,7 @@ mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const cha
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(RPL_MODLIST),
|
sendto_one(source_p, form_str(RPL_MODLIST),
|
||||||
me.name, source_p->name, modlist[i]->name,
|
me.name, source_p->name, modlist[i]->name,
|
||||||
(unsigned long)(uintptr_t)modlist[i]->address,
|
(unsigned long)(uintptr_t)modlist[i]->address, modlist[i]->version,
|
||||||
modlist[i]->version,
|
|
||||||
modlist[i]->core ? "(core)" : "");
|
modlist[i]->core ? "(core)" : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,8 +583,6 @@ mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const cha
|
||||||
static int
|
static int
|
||||||
mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||||
{
|
{
|
||||||
int modnum;
|
|
||||||
|
|
||||||
if(!IsOperAdmin(source_p))
|
if(!IsOperAdmin(source_p))
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
||||||
|
@ -481,6 +590,35 @@ mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(parc > 1)
|
||||||
|
{
|
||||||
|
sendto_match_servs(source_p, parv[1], CAP_ENCAP, NOCAPS,
|
||||||
|
"ENCAP %s MODRESTART", parv[1]);
|
||||||
|
if (match(parv[1], me.name) == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_modrestart(source_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
me_modrestart(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||||
|
{
|
||||||
|
if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
|
||||||
|
{
|
||||||
|
sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
|
||||||
|
"to load modules on this server.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_modrestart(source_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_modrestart(struct Client *source_p)
|
||||||
|
{
|
||||||
|
int modnum;
|
||||||
|
|
||||||
sendto_one_notice(source_p, ":Reloading all modules");
|
sendto_one_notice(source_p, ":Reloading all modules");
|
||||||
|
|
||||||
modnum = num_mods;
|
modnum = num_mods;
|
||||||
|
@ -491,7 +629,7 @@ mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const
|
||||||
load_core_modules(0);
|
load_core_modules(0);
|
||||||
rehash(0);
|
rehash(0);
|
||||||
|
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
|
||||||
"Module Restart: %d modules unloaded, %d modules loaded",
|
"Module Restart: %d modules unloaded, %d modules loaded",
|
||||||
modnum, num_mods);
|
modnum, num_mods);
|
||||||
ilog(L_MAIN, "Module Restart: %d modules unloaded, %d modules loaded", modnum, num_mods);
|
ilog(L_MAIN, "Module Restart: %d modules unloaded, %d modules loaded", modnum, num_mods);
|
||||||
|
@ -499,22 +637,6 @@ mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef RTLD_NOW
|
|
||||||
#define RTLD_NOW RTLD_LAZY /* openbsd deficiency */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef RTLD_LOCAL
|
|
||||||
#define RTLD_LOCAL 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CHARYBDIS_PROFILE
|
|
||||||
# ifndef RTLD_PROFILE
|
|
||||||
# warning libdl may not support profiling, sucks. :(
|
|
||||||
# define RTLD_PROFILE 0
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void increase_modlist(void);
|
static void increase_modlist(void);
|
||||||
|
|
||||||
#define MODS_INCREMENT 10
|
#define MODS_INCREMENT 10
|
||||||
|
|
|
@ -391,6 +391,7 @@ static struct mode_table shared_table[] =
|
||||||
{ "rehash", SHARED_REHASH },
|
{ "rehash", SHARED_REHASH },
|
||||||
{ "grant", SHARED_GRANT },
|
{ "grant", SHARED_GRANT },
|
||||||
{ "die", SHARED_DIE },
|
{ "die", SHARED_DIE },
|
||||||
|
{ "module", SHARED_MODULE },
|
||||||
{ "all", SHARED_ALL },
|
{ "all", SHARED_ALL },
|
||||||
{ "none", 0 },
|
{ "none", 0 },
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
|
|
Loading…
Reference in a new issue