diff options
Diffstat (limited to 'src/plugins/fts-lucene/fts-lucene-plugin.c')
-rw-r--r-- | src/plugins/fts-lucene/fts-lucene-plugin.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/src/plugins/fts-lucene/fts-lucene-plugin.c b/src/plugins/fts-lucene/fts-lucene-plugin.c new file mode 100644 index 0000000..7c58fa7 --- /dev/null +++ b/src/plugins/fts-lucene/fts-lucene-plugin.c @@ -0,0 +1,146 @@ +/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "crc32.h" +#include "mail-storage-hooks.h" +#include "lucene-wrapper.h" +#include "fts-user.h" +#include "fts-lucene-plugin.h" + +const char *fts_lucene_plugin_version = DOVECOT_ABI_VERSION; + +struct fts_lucene_user_module fts_lucene_user_module = + MODULE_CONTEXT_INIT(&mail_user_module_register); + +static int +fts_lucene_plugin_init_settings(struct mail_user *user, + struct fts_lucene_settings *set, + const char *str) +{ + const char *const *tmp; + + for (tmp = t_strsplit_spaces(str, " "); *tmp != NULL; tmp++) { + if (str_begins(*tmp, "default_language=")) { + set->default_language = + p_strdup(user->pool, *tmp + 17); + } else if (str_begins(*tmp, "textcat_conf=")) { + set->textcat_conf = p_strdup(user->pool, *tmp + 13); + } else if (str_begins(*tmp, "textcat_dir=")) { + set->textcat_dir = p_strdup(user->pool, *tmp + 12); + } else if (str_begins(*tmp, "whitespace_chars=")) { + set->whitespace_chars = p_strdup(user->pool, *tmp + 17); + } else if (strcmp(*tmp, "normalize") == 0) { + set->normalize = TRUE; + } else if (strcmp(*tmp, "no_snowball") == 0) { + set->no_snowball = TRUE; + } else if (strcmp(*tmp, "mime_parts") == 0) { + set->mime_parts = TRUE; + } else if (strcmp(*tmp, "use_libfts") == 0) { + set->use_libfts = TRUE; + } else { + i_error("fts_lucene: Invalid setting: %s", *tmp); + return -1; + } + } + if (set->textcat_conf != NULL && set->textcat_dir == NULL) { + i_error("fts_lucene: textcat_conf set, but textcat_dir unset"); + return -1; + } + if (set->textcat_conf == NULL && set->textcat_dir != NULL) { + i_error("fts_lucene: textcat_dir set, but textcat_conf unset"); + return -1; + } + if (set->whitespace_chars == NULL) + set->whitespace_chars = ""; +#ifndef HAVE_FTS_STEMMER + if (set->default_language != NULL) { + i_error("fts_lucene: default_language set, " + "but Dovecot built without stemmer support"); + return -1; + } +#else + if (set->default_language == NULL) + set->default_language = "english"; +#endif +#ifndef HAVE_FTS_TEXTCAT + if (set->textcat_conf != NULL) { + i_error("fts_lucene: textcat_dir set, " + "but Dovecot built without textcat support"); + return -1; + } +#endif + return 0; +} + +uint32_t fts_lucene_settings_checksum(const struct fts_lucene_settings *set) +{ + uint32_t crc; + + if (set->use_libfts) + return crc32_str("l"); + + /* checksum is always different when compiling with/without stemmer */ + crc = set->default_language == NULL ? 0 : + crc32_str(set->default_language); + crc = crc32_str_more(crc, set->whitespace_chars); + if (set->normalize) + crc = crc32_str_more(crc, "n"); + if (set->no_snowball) + crc = crc32_str_more(crc, "s"); + /* don't include mime_parts here, since changing it doesn't + necessarily need the index to be rebuilt */ + return crc; +} + +static void fts_lucene_mail_user_deinit(struct mail_user *user) +{ + struct fts_lucene_user *fuser = FTS_LUCENE_USER_CONTEXT_REQUIRE(user); + + fts_mail_user_deinit(user); + fuser->module_ctx.super.deinit(user); +} + +static void fts_lucene_mail_user_created(struct mail_user *user) +{ + struct mail_user_vfuncs *v = user->vlast; + struct fts_lucene_user *fuser; + const char *env, *error; + + fuser = p_new(user->pool, struct fts_lucene_user, 1); + env = mail_user_plugin_getenv(user, "fts_lucene"); + if (env == NULL) + env = ""; + + if (fts_lucene_plugin_init_settings(user, &fuser->set, env) < 0) { + /* invalid settings, disabling */ + return; + } + if (fts_mail_user_init(user, fuser->set.use_libfts, &error) < 0) { + i_error("fts_lucene: %s", error); + return; + } + + fuser->module_ctx.super = *v; + user->vlast = &fuser->module_ctx.super; + v->deinit = fts_lucene_mail_user_deinit; + MODULE_CONTEXT_SET(user, fts_lucene_user_module, fuser); +} + +static struct mail_storage_hooks fts_lucene_mail_storage_hooks = { + .mail_user_created = fts_lucene_mail_user_created +}; + +void fts_lucene_plugin_init(struct module *module ATTR_UNUSED) +{ + fts_backend_register(&fts_backend_lucene); + mail_storage_hooks_add(module, &fts_lucene_mail_storage_hooks); +} + +void fts_lucene_plugin_deinit(void) +{ + fts_backend_unregister(fts_backend_lucene.name); + mail_storage_hooks_remove(&fts_lucene_mail_storage_hooks); + lucene_shutdown(); +} + +const char *fts_lucene_plugin_dependencies[] = { "fts", NULL }; |