#include "lib.h"
#include "array.h"
#include "str.h"
+#include "settings.h"
+#include "settings-parser.h"
#include "mail-user.h"
#include "mail-storage-private.h"
#include "mail-storage-hooks.h"
charset_alias_to_utf8
};
-struct charset_alias {
- const char *charset;
- const char *alias;
+struct charset_alias_settings {
+ pool_t pool;
+
+ ARRAY_TYPE(const_string) charset_aliases;
+};
+
+#undef DEF
+#define DEF(type, name) \
+ SETTING_DEFINE_STRUCT_##type(#name, name, struct charset_alias_settings)
+static const struct setting_define charset_alias_setting_defines[] = {
+ DEF(STRLIST, charset_aliases),
+
+ SETTING_DEFINE_LIST_END
+};
+static const struct charset_alias_settings charset_alias_default_settings = {
+ .charset_aliases = ARRAY_INIT,
};
-static ARRAY(struct charset_alias) charset_aliases;
-static pool_t charset_alias_pool;
+const struct setting_parser_info charset_alias_setting_parser_info = {
+ .name = "charset_alias",
+
+ .defines = charset_alias_setting_defines,
+ .defaults = &charset_alias_default_settings,
+
+ .struct_size = sizeof(struct charset_alias_settings),
+ .pool_offset1 = 1 + offsetof(struct charset_alias_settings, pool),
+};
+
+static const struct charset_alias_settings *charset_alias_set;
static int charset_alias_user_refcount = 0;
struct charset_alias_user {
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;
- }
- }
+ const char *const *str;
+ unsigned int i, count;
+
+ if (!array_is_created(&charset_alias_set->charset_aliases))
+ return charset;
+
+ str = array_get(&charset_alias_set->charset_aliases, &count);
+ i_assert(count % 2 == 0);
+ for (i = 0; i < count; i += 2) {
+ if (strcasecmp(charset, str[i]) == 0)
+ return str[i + 1];
}
return charset;
}
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] != NULL; i++) {
- value = strchr(keyvalues[i], '=');
- if (value == NULL) {
- e_error(user->event,
- "charset_alias: Missing '=' in charset_aliases setting");
- continue;
- }
- key = t_strdup_until(keyvalues[i], value++);
- if (key[0] == '\0' || value[0] == '\0') {
- e_error(user->event,
- "charset_alias: charset or alias missing in charset_aliases setting");
- continue;
- }
- if (strcasecmp(key, value) != 0) {
- e_debug(user->event, "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_push_back(&charset_aliases, &alias);
- }
- }
- return array_count(&charset_aliases);
-}
-
static void charset_alias_utf8_vfuncs_set(void)
{
original_charset_utf8_vfuncs = charset_utf8_vfuncs;
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);
+ settings_free(charset_alias_set);
}
cuser->module_ctx.super.deinit(user);
{
struct mail_user_vfuncs *v = user->vlast;
struct charset_alias_user *cuser;
- const char *str;
+ const char *error;
cuser = p_new(user->pool, struct charset_alias_user, 1);
cuser->module_ctx.super = *v;
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();
- }
+ if (settings_get(user->event,
+ &charset_alias_setting_parser_info, 0,
+ &charset_alias_set, &error) < 0) {
+ user->error = p_strdup(user->pool, error);
+ return;
}
+
+ if (!array_is_empty(&charset_alias_set->charset_aliases))
+ charset_alias_utf8_vfuncs_set();
}
MODULE_CONTEXT_SET(user, charset_alias_user_module, cuser);