bool doveadm_has_unloaded_plugin(const char *name) { struct module *module; DIR *dir; struct dirent *d; const char *plugin_name; unsigned int name_len = strlen(name); bool found = FALSE; /* first check that it's not actually loaded */ for (module = modules; module != NULL; module = module->next) { if (strcmp(module_get_plugin_name(module), name) == 0) return FALSE; } dir = opendir(DOVEADM_MODULEDIR); if (dir == NULL) return FALSE; while ((d = readdir(dir)) != NULL) { plugin_name = module_file_get_name(d->d_name); if (strncmp(plugin_name, "doveadm_", 8) == 0) plugin_name += 8; if (strncmp(plugin_name, name, name_len) == 0 && (plugin_name[name_len] == '\0' || strcmp(plugin_name + name_len, "_plugin") == 0)) { found = TRUE; break; } } (void)closedir(dir); return found; }
for (; *names != NULL; names++) { if (strcmp(*names, name) == 0) { *names = ""; return TRUE; } } return FALSE; } static void check_duplicates(ARRAY_TYPE(const_string) *names, const char *name, const char *dir) { const char *const *names_p, *base_name, *tmp; unsigned int i, count; base_name = module_file_get_name(name); names_p = array_get(names, &count); for (i = 0; i < count; i++) { tmp = module_file_get_name(names_p[i]); if (strcmp(tmp, base_name) == 0) i_fatal("Multiple files for module %s: %s/%s, %s/%s", base_name, dir, name, dir, names_p[i]); } } struct module *module_dir_find(struct module *modules, const char *name) { struct module *module; unsigned int len = strlen(name);
void sieve_plugins_load (struct sieve_instance *svinst, const char *path, const char *plugins) { struct module *module; struct module_dir_load_settings mod_set; const char **module_names; unsigned int i; /* Determine what to load */ if ( path == NULL && plugins == NULL ) { path = sieve_setting_get(svinst, "sieve_plugin_dir"); plugins = sieve_setting_get(svinst, "sieve_plugins"); } if ( plugins == NULL || *plugins == '\0' ) return; if ( path == NULL || *path == '\0' ) path = MODULEDIR"/sieve"; memset(&mod_set, 0, sizeof(mod_set)); mod_set.abi_version = PIGEONHOLE_ABI_VERSION; mod_set.require_init_funcs = TRUE; mod_set.debug = FALSE; /* Load missing plugin modules */ sieve_modules = module_dir_load_missing (sieve_modules, path, plugins, &mod_set); /* Call plugin load functions for this Sieve instance */ if ( svinst->plugins == NULL ) { sieve_modules_refcount++; } module_names = t_strsplit_spaces(plugins, ", "); for (i = 0; module_names[i] != NULL; i++) { /* Allow giving the module names also in non-base form. */ module_names[i] = module_file_get_name(module_names[i]); } for (i = 0; module_names[i] != NULL; i++) { struct sieve_plugin *plugin; const char *name = module_names[i]; sieve_plugin_load_func_t load_func; /* Find the module */ module = sieve_plugin_module_find(name); i_assert(module != NULL); /* Check whether the plugin is already loaded in this instance */ plugin = svinst->plugins; while ( plugin != NULL ) { if ( plugin->module == module ) break; plugin = plugin->next; } /* Skip it if it is loaded already */ if ( plugin != NULL ) continue; /* Create plugin list item */ plugin = p_new(svinst->pool, struct sieve_plugin, 1); plugin->module = module; /* Call load function */ load_func = (sieve_plugin_load_func_t) module_get_symbol (module, t_strdup_printf("%s_load", module->name)); if ( load_func != NULL ) { load_func(svinst, &plugin->context); } /* Add plugin to the instance */ if ( svinst->plugins == NULL ) svinst->plugins = plugin; else { struct sieve_plugin *plugin_last; plugin_last = svinst->plugins; while ( plugin_last->next != NULL ) plugin_last = plugin_last->next; plugin_last->next = plugin; } } }