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