Deferred capability notifications from modules
Reloading modules sends CAP DEL followed by an immediate CAP NEW: :staberinde.local CAP * DEL :account-tag :staberinde.local CAP * NEW :account-tag This isn't very nice. /modrestart is particularly bad. In order to avoid doing this, we remember the capability set at the beginning of module operations, compare that with the set afterwards, and report only the differences with CAP {DEL,NEW}.
This commit is contained in:
parent
9ac0390734
commit
28cc8bb924
3 changed files with 43 additions and 6 deletions
|
@ -122,6 +122,10 @@ struct mapi_mheader_av2
|
||||||
void mod_add_path(const char *path);
|
void mod_add_path(const char *path);
|
||||||
void mod_clear_paths(void);
|
void mod_clear_paths(void);
|
||||||
|
|
||||||
|
/* cap-notify utilities */
|
||||||
|
extern void mod_remember_clicaps(void);
|
||||||
|
extern void mod_notify_clicaps(void);
|
||||||
|
|
||||||
/* load a module */
|
/* load a module */
|
||||||
extern void load_module(char *path);
|
extern void load_module(char *path);
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,29 @@ init_modules(void)
|
||||||
mod_add_path(ircd_paths[IRCD_PATH_AUTOLOAD_MODULES]);
|
mod_add_path(ircd_paths[IRCD_PATH_AUTOLOAD_MODULES]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int prev_caps;
|
||||||
|
|
||||||
|
void
|
||||||
|
mod_remember_clicaps(void)
|
||||||
|
{
|
||||||
|
prev_caps = capability_index_mask(cli_capindex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mod_notify_clicaps(void)
|
||||||
|
{
|
||||||
|
unsigned int cur_caps = capability_index_mask(cli_capindex);
|
||||||
|
unsigned int del = prev_caps & ~cur_caps;
|
||||||
|
unsigned int new = cur_caps & ~prev_caps;
|
||||||
|
|
||||||
|
if (del)
|
||||||
|
sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * DEL :%s",
|
||||||
|
me.name, capability_index_list(cli_capindex, del));
|
||||||
|
if (new)
|
||||||
|
sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * NEW :%s",
|
||||||
|
me.name, capability_index_list(cli_capindex, new));
|
||||||
|
}
|
||||||
|
|
||||||
/* mod_find_path()
|
/* mod_find_path()
|
||||||
*
|
*
|
||||||
* input - path
|
* input - path
|
||||||
|
@ -382,10 +405,7 @@ unload_one_module(const char *name, bool warn)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->cap_id != NULL)
|
if (m->cap_id != NULL)
|
||||||
{
|
|
||||||
capability_orphan(idx, m->cap_name);
|
capability_orphan(idx, m->cap_name);
|
||||||
sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * DEL :%s", me.name, m->cap_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -600,10 +620,7 @@ load_a_module(const char *path, bool warn, int origin, bool core)
|
||||||
|
|
||||||
result = capability_put(idx, m->cap_name, m->cap_ownerdata);
|
result = capability_put(idx, m->cap_name, m->cap_ownerdata);
|
||||||
if (m->cap_id != NULL)
|
if (m->cap_id != NULL)
|
||||||
{
|
|
||||||
*(m->cap_id) = result;
|
*(m->cap_id) = result;
|
||||||
sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * ADD :%s", me.name, m->cap_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -671,6 +688,8 @@ modules_do_restart(void *unused)
|
||||||
unsigned int modnum = 0;
|
unsigned int modnum = 0;
|
||||||
rb_dlink_node *ptr, *nptr;
|
rb_dlink_node *ptr, *nptr;
|
||||||
|
|
||||||
|
mod_remember_clicaps();
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, module_list.head)
|
RB_DLINK_FOREACH_SAFE(ptr, nptr, module_list.head)
|
||||||
{
|
{
|
||||||
struct module *mod = ptr->data;
|
struct module *mod = ptr->data;
|
||||||
|
@ -694,6 +713,8 @@ modules_do_restart(void *unused)
|
||||||
load_core_modules(false);
|
load_core_modules(false);
|
||||||
rehash(false);
|
rehash(false);
|
||||||
|
|
||||||
|
mod_notify_clicaps();
|
||||||
|
|
||||||
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));
|
||||||
|
|
|
@ -274,9 +274,13 @@ do_modload(struct Client *source_p, const char *module)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod_remember_clicaps();
|
||||||
|
|
||||||
origin = strcmp(module, m_bn) == 0 ? MAPI_ORIGIN_CORE : MAPI_ORIGIN_EXTENSION;
|
origin = strcmp(module, m_bn) == 0 ? MAPI_ORIGIN_CORE : MAPI_ORIGIN_EXTENSION;
|
||||||
load_one_module(module, origin, false);
|
load_one_module(module, origin, false);
|
||||||
|
|
||||||
|
mod_notify_clicaps();
|
||||||
|
|
||||||
rb_free(m_bn);
|
rb_free(m_bn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,9 +304,13 @@ do_modunload(struct Client *source_p, const char *module)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod_remember_clicaps();
|
||||||
|
|
||||||
if(unload_one_module(m_bn, true) == false)
|
if(unload_one_module(m_bn, true) == false)
|
||||||
sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
|
sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
|
||||||
|
|
||||||
|
mod_notify_clicaps();
|
||||||
|
|
||||||
rb_free(m_bn);
|
rb_free(m_bn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,6 +330,8 @@ do_modreload(struct Client *source_p, const char *module)
|
||||||
|
|
||||||
check_core = mod->core;
|
check_core = mod->core;
|
||||||
|
|
||||||
|
mod_remember_clicaps();
|
||||||
|
|
||||||
if(unload_one_module(m_bn, true) == false)
|
if(unload_one_module(m_bn, true) == false)
|
||||||
{
|
{
|
||||||
sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
|
sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
|
||||||
|
@ -337,6 +347,8 @@ do_modreload(struct Client *source_p, const char *module)
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod_notify_clicaps();
|
||||||
|
|
||||||
rb_free(m_bn);
|
rb_free(m_bn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue