#include "match.h"
#include "s_serv.h"
#include "capability.h"
+#include "hash.h"
#include <ltdl.h>
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()
*
* input - path
}
if (m->cap_id != NULL)
- {
capability_orphan(idx, m->cap_name);
- sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * DEL :%s", me.name, m->cap_name);
- }
}
}
break;
lt_dlhandle tmpptr;
char *mod_displayname, *c;
const char *ver, *description = NULL;
- size_t module_ext_len = strlen(LT_MODULE_EXT);
int *mapi_version;
result = capability_put(idx, m->cap_name, m->cap_ownerdata);
if (m->cap_id != NULL)
- {
*(m->cap_id) = result;
- sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * ADD :%s", me.name, m->cap_name);
- }
}
}
}
rb_free(mod_displayname);
return true;
}
+
+void
+modules_do_reload(void *info_)
+{
+ struct modreload *info = info_;
+ struct module *mod;
+ int check_core;
+ int origin;
+ char *m_bn = rb_basename(info->module);
+ struct Client *source_p = find_id(info->id);
+
+ if((mod = findmodule_byname(m_bn)) == NULL)
+ {
+ if (source_p) sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
+ rb_free(info);
+ rb_free(m_bn);
+ return;
+ }
+
+ origin = mod->origin;
+ check_core = mod->core;
+
+ mod_remember_clicaps();
+
+ if(unload_one_module(m_bn, true) == false)
+ {
+ if (source_p) sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
+ rb_free(info);
+ rb_free(m_bn);
+ return;
+ }
+
+ if((load_one_module(m_bn, 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);
+ }
+
+ mod_notify_clicaps();
+
+ rb_free(info);
+ rb_free(m_bn);
+}
+
+void
+modules_do_restart(void *unused)
+{
+ unsigned int modnum = 0;
+ rb_dlink_node *ptr, *nptr;
+
+ mod_remember_clicaps();
+
+ RB_DLINK_FOREACH_SAFE(ptr, nptr, module_list.head)
+ {
+ struct module *mod = ptr->data;
+ if(!unload_one_module(mod->name, false))
+ {
+ ilog(L_MAIN, "Module Restart: %s was not unloaded %s",
+ mod->name,
+ mod->core? "(core module)" : "");
+
+ if(!mod->core)
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "Module Restart: %s failed to unload",
+ mod->name);
+ continue;
+ }
+
+ modnum++;
+ }
+
+ load_all_modules(false);
+ load_core_modules(false);
+ rehash(false);
+
+ mod_notify_clicaps();
+
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "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));
+}