Example #1
0
/*!
 * After loading a module, call this function to register
 * the plugin with AbiWord
 *
 * \return true on success, false on failure
 */
bool XAP_Module::registerThySelf ()
{
	UT_ASSERT (m_bLoaded && !m_bRegistered);

	if (!m_bLoaded)     return false;
	if ( m_bRegistered) return false;

	m_bRegistered = true; // i.e., don't try to register again

	typedef int (*plugin_init_func_t) (XAP_ModuleInfo *) ;
	plugin_init_func_t plugin_init_func;
	plugin_init_func_t *pfunc = &plugin_init_func;

	m_iStatus = 0;

	if (m_fnRegister)
		{
			memset (&m_info, 0, sizeof (m_info)); // ensure that this is null
			m_iStatus = m_fnRegister (&m_info);
		}
	else if (resolveSymbol ("abi_plugin_register", reinterpret_cast<void **>(pfunc)))
		{
			if (!plugin_init_func)
				{
					// damn this sucks. probably not an abiword plugin
					return false;
				}
			memset (&m_info, 0, sizeof (m_info)); // ensure that this is null
			m_iStatus = plugin_init_func (&m_info);
		}
	return (m_iStatus ? true : false);
}
Example #2
0
void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {

	void *plugin_handle = NULL;
	char *plugin_abs_path = NULL;
	char *plugin_filename = NULL;

	int need_free = 0;
	char *plugin_name = uwsgi_strip(uwsgi_str(plugin));
	char *plugin_symbol_name_start = plugin_name;

	struct uwsgi_plugin *up;
	char linkpath_buf[1024], linkpath[1024];
	int linkpath_size;

	char *colon = strchr(plugin_name, ':');
	if (colon) {
		colon[0] = 0;
		modifier = atoi(plugin_name);
		plugin_name = colon + 1;
		colon[0] = ':';
	}

	char *init_func = strchr(plugin_name, '|');
	if (init_func) {
		init_func[0] = 0;
		init_func++;	
	}

	if (!uwsgi_endswith(plugin_name, "_plugin.so")) {
		plugin_name = uwsgi_concat2(plugin_name, "_plugin.so");
		need_free = 1;
	}

	plugin_symbol_name_start = plugin_name;

	// step 1: check for absolute plugin (stop if it fails)
	if (strchr(plugin_name, '/')) {
#ifdef UWSGI_ELF
		uwsgi_plugin_parse_section(plugin_name);
#endif
		plugin_handle = dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL);
		if (!plugin_handle) {
			if (!has_option)
				uwsgi_log("%s\n", dlerror());
			goto end;
		}
		plugin_symbol_name_start = uwsgi_get_last_char(plugin_name, '/');
		plugin_symbol_name_start++;
		plugin_abs_path = plugin_name;
		goto success;
	}

	// step dir, check for user-supplied plugins directory
	struct uwsgi_string_list *pdir = uwsgi.plugins_dir;
	while (pdir) {
		plugin_filename = uwsgi_concat3(pdir->value, "/", plugin_name);
#ifdef UWSGI_ELF
		uwsgi_plugin_parse_section(plugin_filename);
#endif
		plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL);
		if (plugin_handle) {
			plugin_abs_path = plugin_filename;
			//free(plugin_filename);
			goto success;
		}
		free(plugin_filename);
		plugin_filename = NULL;
		pdir = pdir->next;
	}

	// last step: search in compile-time plugin_dir
	if (!plugin_handle) {
		plugin_filename = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", plugin_name);
#ifdef UWSGI_ELF
		uwsgi_plugin_parse_section(plugin_filename);
#endif
		plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL);
		plugin_abs_path = plugin_filename;
		//free(plugin_filename);
	}

success:
	if (!plugin_handle) {
		if (!has_option)
			uwsgi_log("!!! UNABLE to load uWSGI plugin: %s !!!\n", dlerror());
	}
	else {
		if (init_func) {
			void (*plugin_init_func)() = dlsym(plugin_handle, init_func);
			if (plugin_init_func) {
				plugin_init_func();
			}
		}
		char *plugin_entry_symbol = uwsgi_concat2n(plugin_symbol_name_start, strlen(plugin_symbol_name_start) - 3, "", 0);
		up = dlsym(plugin_handle, plugin_entry_symbol);
		if (!up) {
			// is it a link ?
			memset(linkpath_buf, 0, 1024);
			memset(linkpath, 0, 1024);
			if ((linkpath_size = readlink(plugin_abs_path, linkpath_buf, 1023)) > 0) {
				do {
					linkpath_buf[linkpath_size] = '\0';
					strncpy(linkpath, linkpath_buf, linkpath_size + 1);
				} while ((linkpath_size = readlink(linkpath, linkpath_buf, 1023)) > 0);
#ifdef UWSGI_DEBUG
				uwsgi_log("%s\n", linkpath);
#endif
				free(plugin_entry_symbol);
				char *slash = uwsgi_get_last_char(linkpath, '/');
				if (!slash) {
					slash = linkpath;
				}
				else {
					slash++;
				}
				plugin_entry_symbol = uwsgi_concat2n(slash, strlen(slash) - 3, "", 0);
				up = dlsym(plugin_handle, plugin_entry_symbol);
			}
		}
		if (up) {
			if (!up->name) {
				uwsgi_log("the loaded plugin (%s) has no .name attribute\n", plugin_name);
				if (dlclose(plugin_handle)) {
					uwsgi_error("dlclose()");
				}
				if (need_free)
					free(plugin_name);
				if (plugin_filename)
					free(plugin_filename);
				free(plugin_entry_symbol);
				return NULL;
			}
			if (plugin_already_loaded(up->name)) {
				if (dlclose(plugin_handle)) {
					uwsgi_error("dlclose()");
				}
				if (need_free)
					free(plugin_name);
				if (plugin_filename)
					free(plugin_filename);
				free(plugin_entry_symbol);
				return NULL;
			}
			if (has_option) {
				struct uwsgi_option *op = up->options;
				int found = 0;
				while (op && op->name) {
					if (!strcmp(has_option, op->name)) {
						found = 1;
						break;
					}
					op++;
				}
				if (!found) {
					if (dlclose(plugin_handle)) {
						uwsgi_error("dlclose()");
					}
					if (need_free)
						free(plugin_name);
					if (plugin_filename)
						free(plugin_filename);
					free(plugin_entry_symbol);
					return NULL;
				}

			}
			if (modifier != -1) {
				fill_plugin_table(modifier, up);
				up->modifier1 = modifier;
			}
			else {
				fill_plugin_table(up->modifier1, up);
			}
			if (need_free)
				free(plugin_name);
			if (plugin_filename)
				free(plugin_filename);
			free(plugin_entry_symbol);

			if (up->on_load)
				up->on_load();
			return plugin_handle;
		}
		if (!has_option)
			uwsgi_log("%s\n", dlerror());
	}

end:
	if (need_free)
		free(plugin_name);
	if (plugin_filename)
		free(plugin_filename);

	return NULL;
}