/*
* For each component, keep an ordered list of ones to call.
*/
-static rbtree_t *components;
+static rbtree_t *components = NULL;
static rbtree_t *module_tree = NULL;
+static rbtree_t *instance_tree = NULL;
+
typedef struct section_type_value_t {
const char *section;
const char *typename;
/*
+ * Compare two module entries
+ */
+static int module_instance_cmp(const void *one, const void *two)
+{
+ const module_instance_t *a = one;
+ const module_instance_t *b = two;
+
+ return strcmp(a->name, b->name);
+}
+
+
+/*
* Free a module instance.
*/
static void module_instance_free(void *data)
{
module_instance_t *this = data;
- if (this->entry->module->detach)
+ if (this->entry->module->detach) {
+ int i;
+
(this->entry->module->detach)(this->insthandle);
+ for (i = 0; i < 16; i++) {
+ if (this->old_insthandle[i]) {
+ (this->entry->module->detach)(this->old_insthandle[i]);
+ }
+ }
+ }
+
#ifdef HAVE_PTHREAD_H
if (this->mutex) {
/*
free(this->mutex);
}
#endif
+ memset(this, 0, sizeof(*this));
free(this);
}
module_entry_t *this = data;
lt_dlclose(this->handle); /* ignore any errors */
+ memset(this, 0, sizeof(*this));
free(this);
}
*/
int detach_modules(void)
{
+ rbtree_free(instance_tree);
rbtree_free(components);
rbtree_free(module_tree);
+ lt_dlexit();
+
return 0;
}
lt_dlhandle handle;
char module_struct[256];
char *p;
- const void *module;
+ const module_t *module;
strlcpy(myentry.name, module_name, sizeof(myentry.name));
node = rbtree_finddata(module_tree, &myentry);
/*
* Before doing anything else, check if it's sane.
*/
- if ((*(const uint32_t *) module) != RLM_MODULE_MAGIC_NUMBER) {
+ if (module->magic != RLM_MODULE_MAGIC_NUMBER) {
lt_dlclose(handle);
cf_log_err(cf_sectiontoitem(cs),
"Invalid version in module '%s'",
{
CONF_SECTION *cs;
const char *name1, *name2;
- module_instance_t *node;
+ module_instance_t *node, myNode;
char module_name[256];
if (!modules) return NULL;
/*
* If there's already a module instance, return it.
*/
- node = cf_data_find(cs, "instance");
+ strlcpy(myNode.name, instname, sizeof(myNode.name));
+ node = rbtree_finddata(instance_tree, &myNode);
if (node) return node;
name1 = cf_section_name1(cs);
}
#endif
- cf_data_add(cs, "instance", node, module_instance_free);
+ rbtree_insert(instance_tree, node);
return node;
}
ci=cf_item_find_next(modules, ci)) {
int i;
void *insthandle = NULL;
+ const char *instname;
+ module_instance_t myNode;
/*
* If it's not a section, ignore it.
if (!cf_item_is_section(ci)) continue;
cs = cf_itemtosection(ci);
+ instname = cf_section_name2(cs);
+ if (!instname) instname = cf_section_name1(cs);
- node = cf_data_find(cs, "instance");
+ strlcpy(myNode.name, instname, sizeof(myNode.name));
+ node = rbtree_finddata(instance_tree, &myNode);
if (!node ||
!node->entry->module->instantiate ||
((node->entry->module->type & RLM_TYPE_HUP_SAFE) == 0)) {
rad_listen_t *listener;
int null_server = FALSE;
+ if (reload) return 0;
+
/*
* If necessary, initialize libltdl.
*/
radlog(L_ERR, "Failed to initialize modules\n");
return -1;
}
- } else {
- rbtree_free(components);
+
+ instance_tree = rbtree_create(module_instance_cmp,
+ module_instance_free, 0);
+ if (!instance_tree) {
+ radlog(L_ERR, "Failed to initialize modules\n");
+ return -1;
+ }
}
components = rbtree_create(indexed_modcallable_cmp,