示例#1
0
static int module_add(irc_connection *con, config_group *group, const char *module_file)
{
	init_module_func mod_generic_init;
	module_message_handler mod_msg_handler;
	module_init mod_init;
	module_close mod_close;

	if (module_by_name(con, Module_name(module_file), NULL)) return -9;

	void* module_libfile = dlopen(module_file, RTLD_NOW | RTLD_LOCAL);
	if (!module_libfile) {
		Printerr("dlopen: %s\n", dlerror());
		return -1;
	}

	module_message_handler module_msg_handler = dlsym(module_libfile, "module_message_handler");
	if (!module_msg_handler) return -2;

	LINK_FUNC(mod_generic_init, "init_module_generic", -3);
	mod_generic_init(irc_send_raw_msg, config_get_value, group);
	LINK_FUNC(mod_init, "module_init", -4);
	LINK_FUNC(mod_msg_handler, "module_message_handler", -5);
	LINK_FUNC(mod_close, "module_close", -6);

	if (mod_init(con)) return -7;

	module_listitem *p = malloc(sizeof(module_listitem));
	if (!p) return -8;

	/* Ok, everything seems to be fine. So we can finally populate the
	 * module structure's pointers and add it to the list of 
	 * loaded modules! */

	p->name = Module_name(module_file);
	p->next = NULL;
	p->libhandle = module_libfile;
	p->init = mod_init;
	p->handle_msg = module_msg_handler;
	p->close = mod_close;

	module_listitem *l = con->modules;
	if (l) {
		while (l->next) l = l->next;
		l->next = p;
	}
	else
		con->modules = p;

	con->module_count++;

	return 0;
}
示例#2
0
int module_unload(irc_connection *con, const char *module_name)
{
	int ret = 0;

	module_listitem *l = con->modules;
	module_listitem *l2;

	l = module_by_name(con, module_name, &l2);

	if (l == NULL) return -9; // Not found!

	// Remove item from list
	if (l2 == NULL) con->modules = l->next;
	else 		l2->next = l->next;

	free_module(l);

	con->module_count--;

	return ret;
}
示例#3
0
/** Resolve polymorphic item's from a module's #CONF_SECTION to a subsection in another module
 *
 * This allows certain module sections to reference module sections in other instances
 * of the same module and share #CONF_DATA associated with them.
 *
 * @verbatim
   example {
   	data {
   		...
   	}
   }

   example inst {
   	data = example
   }
 * @endverbatim
 *
 * @param[out] out where to write the pointer to a module's config section.  May be NULL on success,
 *	indicating the config item was not found within the module #CONF_SECTION
 *	or the chain of module references was followed and the module at the end of the chain
 *	did not a subsection.
 * @param[in] module #CONF_SECTION.
 * @param[in] name of the polymorphic sub-section.
 * @return
 *	- 0 on success with referenced section.
 *	- 1 on success with local section.
 *	- -1 on failure.
 */
int module_sibling_section_find(CONF_SECTION **out, CONF_SECTION *module, char const *name)
{
	CONF_PAIR		*cp;
	CONF_SECTION		*cs;
	CONF_DATA const		*cd;


	module_instance_t	*mi;
	char const		*inst_name;

#define FIND_SIBLING_CF_KEY "find_sibling"

	*out = NULL;

	/*
	 *	Is a real section (not referencing sibling module).
	 */
	cs = cf_section_find(module, name, NULL);
	if (cs) {
		*out = cs;

		return 0;
	}

	/*
	 *	Item omitted completely from module config.
	 */
	cp = cf_pair_find(module, name);
	if (!cp) return 0;

	if (cf_data_find(module, CONF_SECTION, FIND_SIBLING_CF_KEY)) {
		cf_log_err(cp, "Module reference loop found");

		return -1;
	}
	cd = cf_data_add(module, module, FIND_SIBLING_CF_KEY, false);

	/*
	 *	Item found, resolve it to a module instance.
	 *	This triggers module loading, so we don't have
	 *	instantiation order issues.
	 */
	inst_name = cf_pair_value(cp);
	mi = module_by_name(NULL, inst_name);
	if (!mi) {
		cf_log_err(cp, "Unknown module instance \"%s\"", inst_name);

		return -1;
	}

	if (!mi->instantiated) {
		CONF_SECTION *parent = module;

		/*
		 *	Find the root of the config...
		 */
		do {
			CONF_SECTION *tmp;

			tmp = cf_item_to_section(cf_parent(parent));
			if (!tmp) break;

			parent = tmp;
		} while (true);

		_module_instantiate(module_by_name(NULL, inst_name), NULL);
	}

	/*
	 *	Remove the config data we added for loop
	 *	detection.
	 */
	cf_data_remove(module, cd);

	/*
	 *	Check the module instances are of the same type.
	 */
	if (strcmp(cf_section_name1(mi->dl_inst->conf), cf_section_name1(module)) != 0) {
		cf_log_err(cp, "Referenced module is a rlm_%s instance, must be a rlm_%s instance",
			      cf_section_name1(mi->dl_inst->conf), cf_section_name1(module));

		return -1;
	}

	*out = cf_section_find(mi->dl_inst->conf, name, NULL);

	return 1;
}