charset-alias-plugin.c revision 5addf4e0ac50a99af25a1b1ef3def67f6d1595de
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi/* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi#include "lib.h"
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi#include "array.h"
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi#include "str.h"
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi#include "mail-user.h"
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi#include "mail-storage-private.h"
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi#include "mail-storage-hooks.h"
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi#include "charset-utf8-private.h"
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi#include "charset-alias-plugin.h"
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi#define CHARSET_ALIAS_USER_CONTEXT(obj) \
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi MODULE_CONTEXT_REQUIRE(obj, charset_alias_user_module)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic MODULE_CONTEXT_DEFINE_INIT(charset_alias_user_module,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi &mail_user_module_register);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärviconst char *charset_alias_plugin_version = DOVECOT_ABI_VERSION;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic int charset_alias_to_utf8_begin(const char *charset,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi normalizer_func_t *normalizer,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi struct charset_translation **t_r);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic void charset_alias_to_utf8_end(struct charset_translation *t);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic void charset_alias_to_utf8_reset(struct charset_translation *t);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic enum charset_result charset_alias_to_utf8(struct charset_translation *t,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi const unsigned char *src,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi size_t *src_size, buffer_t *dest);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi/* charset_utf8_vfuncs is defined in lib-charset/charset-utf8.c */
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärviextern const struct charset_utf8_vfuncs *charset_utf8_vfuncs;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic const struct charset_utf8_vfuncs *original_charset_utf8_vfuncs;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic const struct charset_utf8_vfuncs charset_alias_utf8_vfuncs = {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi charset_alias_to_utf8_begin,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi charset_alias_to_utf8_end,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi charset_alias_to_utf8_reset,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi charset_alias_to_utf8
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi};
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistruct charset_alias {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi const char *charset;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi const char *alias;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi};
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic ARRAY(struct charset_alias) charset_aliases;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic pool_t charset_alias_pool;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic int charset_alias_user_refcount = 0;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistruct charset_alias_user {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi union mail_user_module_context module_ctx;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi};
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic const char *charset_alias_get_alias(const char *charset)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi const struct charset_alias* elem;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi const char *key;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (array_is_created(&charset_aliases)) {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi key = t_str_lcase(charset);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi array_foreach(&charset_aliases, elem) {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (strcmp(key, elem->charset) == 0) {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi return elem->alias;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi return charset;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic int charset_alias_to_utf8_begin(const char *charset,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi normalizer_func_t *normalizer,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi struct charset_translation **t_r)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi i_assert(original_charset_utf8_vfuncs != NULL);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi charset = charset_alias_get_alias(charset);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi return original_charset_utf8_vfuncs->to_utf8_begin(charset, normalizer, t_r);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic void charset_alias_to_utf8_end(struct charset_translation *t)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi i_assert(original_charset_utf8_vfuncs != NULL);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi return original_charset_utf8_vfuncs->to_utf8_end(t);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic void charset_alias_to_utf8_reset(struct charset_translation *t)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi i_assert(original_charset_utf8_vfuncs != NULL);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi return original_charset_utf8_vfuncs->to_utf8_reset(t);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic enum charset_result charset_alias_to_utf8(struct charset_translation *t,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi const unsigned char *src,
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi size_t *src_size, buffer_t *dest)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi i_assert(original_charset_utf8_vfuncs != NULL);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi return original_charset_utf8_vfuncs->to_utf8(t, src, src_size, dest);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic unsigned int charset_aliases_init(struct mail_user *user, pool_t pool, const char *str)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi const char *key, *value, *const *keyvalues;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi struct charset_alias alias;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi int i;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi i_assert(!array_is_created(&charset_aliases));
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi p_array_init(&charset_aliases, pool, 1);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi keyvalues = t_strsplit_spaces(str, " ");
5addf4e0ac50a99af25a1b1ef3def67f6d1595deMartti Rannanjärvi for (i = 0; keyvalues[i] != NULL; i++) {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi value = strchr(keyvalues[i], '=');
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (value == NULL) {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi i_error("charset_alias: Missing '=' in charset_aliases setting");
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi continue;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi key = t_strdup_until(keyvalues[i], value++);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (key[0] == '\0' || value[0] == '\0') {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi i_error("charset_alias: charset or alias missing in charset_aliases setting");
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi continue;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (strcasecmp(key, value) != 0) {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (user->mail_debug)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi i_debug("charset_alias: add charset-alias %s for %s", value, key);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi alias.charset = p_strdup(pool, t_str_lcase(key));
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi alias.alias = p_strdup(pool, value);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi array_append(&charset_aliases, &alias, 1);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi return array_count(&charset_aliases);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic void charset_alias_utf8_vfuncs_set(void)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi original_charset_utf8_vfuncs = charset_utf8_vfuncs;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi charset_utf8_vfuncs = &charset_alias_utf8_vfuncs;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic void charset_alias_utf8_vfuncs_reset(void)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (original_charset_utf8_vfuncs != NULL) {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi charset_utf8_vfuncs = original_charset_utf8_vfuncs;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi original_charset_utf8_vfuncs = NULL;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic void charset_alias_mail_user_deinit(struct mail_user *user)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi struct charset_alias_user *cuser = CHARSET_ALIAS_USER_CONTEXT(user);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi i_assert(charset_alias_user_refcount > 0);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (--charset_alias_user_refcount == 0) {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi charset_alias_utf8_vfuncs_reset();
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi array_free(&charset_aliases);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi pool_unref(&charset_alias_pool);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi cuser->module_ctx.super.deinit(user);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic void charset_alias_mail_user_created(struct mail_user *user)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi struct mail_user_vfuncs *v = user->vlast;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi struct charset_alias_user *cuser;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi const char *str;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi cuser = p_new(user->pool, struct charset_alias_user, 1);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi cuser->module_ctx.super = *v;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi user->vlast = &cuser->module_ctx.super;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi v->deinit = charset_alias_mail_user_deinit;
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (charset_alias_user_refcount++ == 0) {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi charset_alias_pool = pool_alloconly_create("charset_alias alias list", 128);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi str = mail_user_plugin_getenv(user, "charset_aliases");
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (str != NULL && str[0] != '\0') {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi if (charset_aliases_init(user, charset_alias_pool, str) > 0) {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi charset_alias_utf8_vfuncs_set();
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi }
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi MODULE_CONTEXT_SET(user, charset_alias_user_module, cuser);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvistatic struct mail_storage_hooks charset_alias_mail_storage_hooks = {
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi .mail_user_created = charset_alias_mail_user_created
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi};
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvivoid charset_alias_plugin_init(struct module *module)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi mail_storage_hooks_add(module, &charset_alias_mail_storage_hooks);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvivoid charset_alias_plugin_deinit(void)
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi{
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi mail_storage_hooks_remove(&charset_alias_mail_storage_hooks);
acbcc2709244e470e9bd8b58917f40b2e57d9cb7Martti Rannanjärvi}