]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Use new var_expand
authorAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 20 Aug 2024 09:17:24 +0000 (12:17 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 17 Jan 2025 08:40:00 +0000 (10:40 +0200)
13 files changed:
src/lib-settings/settings-parser.h
src/lib-storage/index/pop3c/pop3c-settings.c
src/lib-storage/index/shared/shared-storage.c
src/lib-storage/mail-storage-service.c
src/lib-storage/mail-storage-service.h
src/lib-storage/mail-storage-settings.c
src/lib-storage/mail-storage.c
src/lib-storage/mail-user-lua.c
src/lib-storage/mail-user.c
src/lib-storage/mail-user.h
src/lib-storage/mailbox-attribute-lua.c
src/lib-storage/mailbox-lua.c
src/lmtp/lmtp-client.c

index 25f37e9fd7d08cd876cfbd39617811cf37929bca..665d6d3396aa54bd1ccbf4fc9a7837305f8c931f 100644 (file)
@@ -4,7 +4,7 @@
 #include "str-parse.h"
 
 struct var_expand_table;
-struct var_expand_func_table;
+struct var_expand_provider;
 
 #define SETTINGS_SEPARATOR '/'
 #define SETTINGS_SEPARATOR_S "/"
index 28e509d2b8791834ed4805ec628b18c643fd2efb..ceaafdaca34c323be28f79ad41b27062e676d904 100644 (file)
@@ -33,7 +33,7 @@ static const struct pop3c_settings pop3c_default_settings = {
        .pop3c_host = "",
        .pop3c_port = 110,
 
-       .pop3c_user = "%u",
+       .pop3c_user = "%{user}",
        .pop3c_master_user = "",
        .pop3c_password = "",
 
index e5bb8e88f5a51ccd884be9855a4d787075187820..8b1d7b271d6eb5fd83903967d0f2cfe01b8d0d9d 100644 (file)
@@ -5,6 +5,7 @@
 #include "str.h"
 #include "ioloop.h"
 #include "settings.h"
+#include "var-expand-new.h"
 #include "index-storage.h"
 #include "mail-storage-service.h"
 #include "mailbox-list-private.h"
@@ -311,16 +312,16 @@ struct shared_mail_user_var_expand_ctx {
 };
 
 static int
-shared_mail_user_var_home(const char *data ATTR_UNUSED, void *context,
-                         const char **value_r,
+shared_mail_user_var_home(const char *key ATTR_UNUSED,
+                         const char **value_r, void *context,
                          const char **error_r)
 {
        struct shared_mail_user_var_expand_ctx *var_expand_ctx = context;
 
        if (var_expand_ctx->nonexistent) {
                /* No need to even bother looking up the home */
-               *value_r = NULL;
-               return 1;
+               *value_r = "";
+               return 0;
        }
        int ret = mail_user_get_home(var_expand_ctx->owner, value_r);
        if (ret < 0) {
@@ -328,9 +329,11 @@ shared_mail_user_var_home(const char *data ATTR_UNUSED, void *context,
                                           var_expand_ctx->owner->username);
                return -1;
        }
-       if (ret == 0)
+       if (ret == 0) {
+               *value_r = "";
                var_expand_ctx->nonexistent = TRUE;
-       return 1;
+       }
+       return 0;
 }
 
 static int
@@ -351,23 +354,21 @@ shared_mail_user_init(struct mail_storage *_storage,
 
        const char *userdomain = domain == NULL ? username :
                t_strdup_printf("%s@%s", username, domain);
-       struct var_expand_table stack_tab[] = {
-               { '\0', p_strdup(user->pool, userdomain), "owner_user" },
-               { '\0', p_strdup(user->pool, username), "owner_username" },
-               { '\0', p_strdup(user->pool, domain), "owner_domain" },
-               { '\0', NULL, NULL },
+       const struct var_expand_table stack_tab[] = {
+               { .key = "owner_user", .value = p_strdup(user->pool, userdomain) },
+               {
+                       .key = "owner_home",
+                       .func = shared_mail_user_var_home,
+               },
+               VAR_EXPAND_TABLE_END
        };
-       struct var_expand_table *tab =
+       const struct var_expand_table *tab =
                p_memdup(user->pool, stack_tab, sizeof(stack_tab));
-       static struct var_expand_func_table func_tab[] = {
-               { "owner_home", shared_mail_user_var_home },
-               { NULL, NULL }
-       };
        struct var_expand_params *params =
                p_new(user->pool, struct var_expand_params, 1);
        params->table = tab;
-       params->func_table = func_tab;
-       params->func_context = var_expand_ctx;
+       params->context = var_expand_ctx;
+       params->event = user->event;
 
        struct event *set_event = event_create(user->event);
        event_add_str(set_event, SETTINGS_EVENT_NAMESPACE_NAME, ns->set->name);
index 22ce5892feb351fe8cc6f98342d59d06105af486..84c137cd5811b70954bef33c5249c244f46f5765 100644 (file)
 #include "str.h"
 #include "time-util.h"
 #include "sleep.h"
-#include "var-expand.h"
 #include "dict.h"
 #include "settings.h"
+#include "var-expand-new.h"
 #include "auth-master.h"
 #include "master-service-private.h"
 #include "mail-user.h"
 #include "mail-namespace.h"
 #include "mail-storage.h"
-#include "mail-storage-private.h"
 #include "mail-storage-service.h"
 
 #include <sys/stat.h>
@@ -376,23 +375,23 @@ get_var_expand_table(struct master_service *service,
                remote_port = dec2str(input->remote_port);
 
        const struct var_expand_table stack_tab[] = {
-               { 'u', input->username, "user" },
-               { 'n', username, "username" },
-               { 'd', domain, "domain" },
-               { 's', service_name, "service" },
-               { 'l', net_ip2addr(&input->local_ip), "local_ip" },
-               { 'r', net_ip2addr(&input->remote_ip), "remote_ip" },
-               { '\0', local_port, "local_port" },
-               { '\0', remote_port," remote_port" },
-               { '\0', input->session_id, "session" },
-               { '\0', auth_user, "auth_user" },
-               { '\0', auth_username, "auth_username" },
-               { '\0', auth_domain, "auth_domain" },
-               { '\0', hostname, "hostname" },
-               { '\0', local_name, "local_name" },
-               { '\0', protocol, "protocol" },
-               { '\0', master_user, "master_user" },
-               { '\0', NULL, NULL }
+               { .key = "user", .value = input->username },
+               { .key = "username", .value = username },
+               { .key = "domain", .value = domain },
+               { .key = "service", .value = service_name },
+               { .key = "local_ip", .value = net_ip2addr(&input->local_ip) },
+               { .key = "remote_ip", .value = net_ip2addr(&input->remote_ip) },
+               { .key = "session", .value = input->session_id },
+               { .key = "auth_user", .value = auth_user },
+               { .key = "auth_username", .value = auth_username },
+               { .key = "auth_domain", .value = auth_domain },
+               { .key = "hostname", .value = hostname },
+               { .key = "local_name", .value = local_name },
+               { .key = "protocol", .value = protocol },
+               { .key = "master_user", .value = master_user },
+               { .key = "local_port", .value = local_port },
+               { .key = "remote_port", .value = remote_port },
+               VAR_EXPAND_TABLE_END
        };
        struct var_expand_table *tab;
 
@@ -401,11 +400,32 @@ get_var_expand_table(struct master_service *service,
        return tab;
 }
 
-const struct var_expand_table *
-mail_storage_service_get_var_expand_table(struct mail_storage_service_ctx *ctx,
-                                         struct mail_storage_service_input *input)
+
+static int
+mail_storage_service_var_userdb(const char *key, const char **value_r,
+                              void *context, const char **error_r ATTR_UNUSED)
+{
+       const struct mail_storage_service_input *input = context;
+
+       *value_r = mail_storage_service_fields_var_expand(key, input->userdb_fields);
+       return 0;
+}
+
+const struct var_expand_provider mail_storage_service_providers[] = {
+       { .key = "userdb", .func = mail_storage_service_var_userdb },
+       VAR_EXPAND_TABLE_END
+};
+
+const struct var_expand_params *
+mail_storage_service_get_var_expand_params(struct mail_storage_service_ctx *ctx,
+                                          struct mail_storage_service_input *input)
 {
-       return get_var_expand_table(ctx->service, NULL, input);
+       struct var_expand_params *params = t_new(struct var_expand_params, 1);
+
+       params->table = get_var_expand_table(ctx->service, NULL, input);
+       params->providers = mail_storage_service_providers;
+       params->context = input;
+       return params;
 }
 
 static int
@@ -743,19 +763,6 @@ mail_storage_service_io_deactivate_user_cb(struct mail_storage_service_user *use
                i_set_failure_prefix("%s", user->service_ctx->default_log_prefix);
 }
 
-static const char *field_get_default(const char *data)
-{
-       const char *p;
-
-       p = strchr(data, ':');
-       if (p == NULL)
-               return "";
-       else {
-               /* default value given */
-               return p+1;
-       }
-}
-
 const char *mail_storage_service_fields_var_expand(const char *data,
                                                   const char *const *fields)
 {
@@ -764,7 +771,7 @@ const char *mail_storage_service_fields_var_expand(const char *data,
        size_t field_name_len;
 
        if (fields == NULL)
-               return field_get_default(data);
+               return "";
 
        field_name_len = strlen(field_name);
        for (i = 0; fields[i] != NULL; i++) {
@@ -772,27 +779,10 @@ const char *mail_storage_service_fields_var_expand(const char *data,
                    fields[i][field_name_len] == '=')
                        return fields[i] + field_name_len+1;
        }
-       return field_get_default(data);
-}
 
-static int
-mail_storage_service_input_var_userdb(const char *data, void *context,
-                                     const char **value_r,
-                                     const char **error_r ATTR_UNUSED)
-{
-       struct mail_storage_service_init_var_expand_ctx *var_expand_ctx = context;
-
-       *value_r = mail_storage_service_fields_var_expand(data,
-                       var_expand_ctx->input->userdb_fields);
-       return 1;
+       return "";
 }
 
-static const struct var_expand_func_table
-mail_storage_service_var_expand_func_table[] = {
-       { "userdb", mail_storage_service_input_var_userdb },
-       { NULL, NULL }
-};
-
 static void
 mail_storage_service_var_expand_callback(void *context,
                                         struct var_expand_params *params_r)
@@ -802,8 +792,8 @@ mail_storage_service_var_expand_callback(void *context,
        params_r->table = get_var_expand_table(var_expand_ctx->ctx->service,
                                               var_expand_ctx->user,
                                               var_expand_ctx->input);
-       params_r->func_table = mail_storage_service_var_expand_func_table;
-       params_r->func_context = var_expand_ctx;
+       params_r->providers = mail_storage_service_providers;
+       params_r->context = (void*)var_expand_ctx->input;
 }
 
 const char *
index 30c0abdb0e61d2eb281ddda81e1eb90c1288cc8c..233198834525398550e6998ae5730b9669d7d4f3 100644 (file)
@@ -179,9 +179,9 @@ mail_storage_service_get_log_prefix(struct mail_storage_service_ctx *ctx);
 enum mail_storage_service_flags
 mail_storage_service_get_flags(struct mail_storage_service_ctx *ctx);
 
-const struct var_expand_table *
-mail_storage_service_get_var_expand_table(struct mail_storage_service_ctx *ctx,
-                                         struct mail_storage_service_input *input);
+const struct var_expand_params *
+mail_storage_service_get_var_expand_params(struct mail_storage_service_ctx *ctx,
+                                          struct mail_storage_service_input *input);
 const char *mail_storage_service_fields_var_expand(const char *data,
                                                   const char *const *fields);
 void mail_storage_service_restore_privileges(uid_t old_uid, const char *old_cwd,
index 94ce15ce0faf7a04dd7145e1cae53bd74654facd..562f55133b366b473b696cd2dbbcde00ab22c082 100644 (file)
@@ -3,10 +3,10 @@
 #include "lib.h"
 #include "array.h"
 #include "hash-format.h"
-#include "var-expand.h"
 #include "unichar.h"
 #include "hostpid.h"
 #include "settings.h"
+#include "var-expand-new.h"
 #include "message-address.h"
 #include "message-header-parser.h"
 #include "smtp-address.h"
@@ -183,7 +183,7 @@ const struct mail_storage_settings mail_storage_default_settings = {
        .maildir_stat_dirs = FALSE,
        .mail_shared_explicit_inbox = FALSE,
        .lock_method = "fcntl:flock:dotlock",
-       .pop3_uidl_format = "%08Xu%08Xv",
+       .pop3_uidl_format = "%{uid|number|hex(8)}%{uidvalidity|number|hex(8)}",
 
        .recipient_delimiter = "+",
 
@@ -362,10 +362,10 @@ static const struct mail_user_settings mail_user_default_settings = {
        .mail_plugins = ARRAY_INIT,
        .mail_plugin_dir = MODULEDIR,
 
-       .mail_log_prefix = "%s(%u)<%{process:pid}><%{session}>: ",
+       .mail_log_prefix = "%{service}(%{user})<%{process:pid}><%{session}>: ",
 
        .hostname = "",
-       .postmaster_address = "postmaster@%{if;%d;ne;;%d;%{hostname}}",
+       .postmaster_address = "postmaster@%{domain|default(hostname)}",
 };
 
 const struct setting_parser_info mail_user_setting_parser_info = {
@@ -577,9 +577,8 @@ mail_storage_settings_ext_check(struct event *event ATTR_UNUSED,
 {
        struct mail_storage_settings *set = _set;
        struct hash_format *format;
-       const char *p, *value, *fname, *error;
+       const char *value, *fname, *error;
        bool uidl_format_ok;
-       char c;
 
        if (set->mailbox_idle_check_interval == 0) {
                *error_r = "mailbox_idle_check_interval must not be 0";
@@ -625,30 +624,36 @@ mail_storage_settings_ext_check(struct event *event ATTR_UNUSED,
        }
 
        uidl_format_ok = FALSE;
-       for (p = set->pop3_uidl_format; *p != '\0'; p++) {
-               if (p[0] != '%' || p[1] == '\0')
-                       continue;
-
-               c = var_get_key(++p);
-               switch (c) {
-               case 'v':
-               case 'u':
-               case 'm':
-               case 'f':
-               case 'g':
-                       uidl_format_ok = TRUE;
-                       break;
-               case '%':
-                       break;
-               default:
+       struct var_expand_program *prog;
+       if (var_expand_program_create(set->pop3_uidl_format, &prog, &error) < 0) {
+               *error_r = t_strdup_printf("Invalid pop3_uidl_format: %s", error);
+               return FALSE;
+       }
+
+       const char *const *pop3_uidl_vars = var_expand_program_variables(prog);
+       const char *const pop3_uidl_allowed_vars[] = {
+               "uidvalidity",
+               "uid",
+               "md5",
+               "filename",
+               "guid",
+               NULL
+       };
+       for (; *pop3_uidl_vars != NULL; pop3_uidl_vars++) {
+               if (!str_array_find(pop3_uidl_allowed_vars, *pop3_uidl_vars)) {
                        *error_r = t_strdup_printf(
-                               "Unknown pop3_uidl_format variable: %%%c", c);
-                       return FALSE;
+                                       "Unknown pop3_uidl_format variable: %%{%s}",
+                                       *pop3_uidl_vars);
+                       break;
                }
+               uidl_format_ok = TRUE;
        }
+       var_expand_program_free(&prog);
+
        if (!uidl_format_ok) {
-               *error_r = "pop3_uidl_format setting doesn't contain any "
-                       "%% variables.";
+               if (pop3_uidl_vars == NULL)
+                       *error_r = "pop3_uidl_format setting doesn't contain any "
+                                  "%% variables.";
                return FALSE;
        }
 
index 582e1e718ea7db12166b86249275220eaec512c4..248492eef332053040694c30930ddaa59fd90c8c 100644 (file)
@@ -17,8 +17,8 @@
 #include "eacces-error.h"
 #include "mkdir-parents.h"
 #include "time-util.h"
-#include "var-expand.h"
 #include "settings.h"
+#include "var-expand-new.h"
 #include "dsasl-client.h"
 #include "imap-date.h"
 #include "mail-index-private.h"
@@ -417,6 +417,18 @@ mail_storage_create_list(struct mail_namespace *ns,
        return ret;
 }
 
+static bool ATTR_PURE pop3_uidl_format_has_md5(const char *fmt)
+{
+       struct var_expand_program *prog;
+       const char *error;
+       if (var_expand_program_create(fmt, &prog, &error) < 0)
+               i_fatal("Invalid pop3_uidl_format: %s", error);
+       const char *const *vars = var_expand_program_variables(prog);
+       bool has_md5 = str_array_find(vars, "md5");
+       var_expand_program_free(&prog);
+       return has_md5;
+}
+
 static int
 mail_storage_create_real(struct mail_namespace *ns, struct event *set_event,
                         enum mail_storage_flags flags,
@@ -424,7 +436,7 @@ mail_storage_create_real(struct mail_namespace *ns, struct event *set_event,
 {
        struct mail_storage *storage_class, *storage = NULL;
        const struct mail_storage_settings *mail_set;
-       const char *p, *driver = NULL;
+       const char *driver = NULL;
        const char *inbox_path_override = NULL;
        const char *root_path_override = NULL;
 
@@ -476,15 +488,8 @@ mail_storage_create_real(struct mail_namespace *ns, struct event *set_event,
                /* if pop3_uidl_format contains %m, we want to keep the
                   header MD5 sums stored even if we're not running POP3
                   right now. */
-               p = ns->list->mail_set->pop3_uidl_format;
-               while ((p = strchr(p, '%')) != NULL) {
-                       if (p[1] == '%')
-                               p += 2;
-                       else if (var_get_key(++p) == 'm') {
-                               flags |= MAIL_STORAGE_FLAG_KEEP_HEADER_MD5;
-                               break;
-                       }
-               }
+               if (pop3_uidl_format_has_md5(ns->list->mail_set->pop3_uidl_format))
+                       flags |= MAIL_STORAGE_FLAG_KEEP_HEADER_MD5;
        }
 
        storage = storage_class->v.alloc();
index 5941d0e7cbb8d79793b6eeeacdf6f9de790d4804..175ed011cef345cc74dc7b6fe7b822d4ec60f990 100644 (file)
@@ -4,7 +4,7 @@
 #include "str.h"
 #include "istream.h"
 #include "array.h"
-#include "var-expand.h"
+#include "var-expand-new.h"
 #include "dlua-script.h"
 #include "dlua-script-private.h"
 #include "mail-storage.h"
@@ -131,10 +131,9 @@ static int lua_storage_mail_user_var_expand(lua_State *L)
        struct mail_user *user = lua_check_storage_mail_user(L, 1);
        const char *error;
        const char *format = luaL_checkstring(L, 2);
-       const struct var_expand_table *table = mail_user_var_expand_table(user);
+       const struct var_expand_params *params = mail_user_var_expand_params(user);
        string_t *str = t_str_new(128);
-       if (var_expand_with_funcs(str, format, table, mail_user_var_expand_func_table,
-                                 user, &error) <= 0) {
+       if (var_expand_new(str, format, params, &error) < 0) {
                return luaL_error(L, "var_expand(%s) failed: %s",
                                  format, error);
        }
index 4b649bfe601c317019151838fcf5a05782edc049..2dfb34f27920f334b0edd09837870c101106fa72 100644 (file)
@@ -13,8 +13,8 @@
 #include "str.h"
 #include "strescape.h"
 #include "strfuncs.h"
-#include "var-expand.h"
 #include "settings.h"
+#include "var-expand-new.h"
 #include "fs-api.h"
 #include "auth-master.h"
 #include "master-service.h"
@@ -63,10 +63,8 @@ static void
 mail_user_var_expand_callback(void *context, struct var_expand_params *params_r)
 {
        struct mail_user *user = context;
-
-       params_r->table = mail_user_var_expand_table(user);
-       params_r->func_table = mail_user_var_expand_func_table;
-       params_r->func_context = user;
+       const struct var_expand_params *params = mail_user_var_expand_params(user);
+       *params_r = *params;
 }
 
 struct mail_user *
@@ -122,12 +120,12 @@ mail_user_expand_plugins_envs(struct mail_user *user,
        str = t_str_new(256);
        envs = array_get_modifiable(&set->plugin_envs, &count);
        i_assert((count % 2) == 0);
+
+       const struct var_expand_params *params = mail_user_var_expand_params(user);
+
        for (i = 0; i < count; i += 2) {
                str_truncate(str, 0);
-               if (var_expand_with_funcs(str, envs[i+1],
-                                         mail_user_var_expand_table(user),
-                                         mail_user_var_expand_func_table, user,
-                                         &error) <= 0) {
+               if (var_expand_new(str, envs[i+1], params, &error) < 0) {
                        user->error = p_strdup_printf(user->pool,
                                "Failed to expand plugin setting %s = '%s': %s",
                                envs[i], envs[i+1], error);
@@ -268,33 +266,31 @@ void mail_user_set_vars(struct mail_user *user, const char *service,
        mail_user_connection_init_from(&user->conn, user->pool, conn);
 }
 
-const struct var_expand_table *
-mail_user_var_expand_table(struct mail_user *user)
+static int
+mail_user_var_expand_func_home(const char *data ATTR_UNUSED, const char **value_r,
+                              void *context, const char **error_r)
+{
+       struct mail_user *user = context;
+
+       if (mail_user_get_home(user, value_r) <= 0) {
+               *error_r = "Setting used home directory (%h) but there is no "
+                       "mail_home and userdb didn't return it";
+               return -1;
+       }
+       return 0;
+}
+
+const struct var_expand_params *
+mail_user_var_expand_params(struct mail_user *user)
 {
        /* use a cached table if possible */
-       if (user->var_expand_table != NULL)
-               return user->var_expand_table;
+       if (user->var_expand_params != NULL)
+               return user->var_expand_params;
 
-       const char *username =
-               p_strdup(user->pool, t_strcut(user->username, '@'));
-       const char *domain = i_strchr_to_next(user->username, '@');
        const char *local_ip = user->conn.local_ip == NULL ? NULL :
                p_strdup(user->pool, net_ip2addr(user->conn.local_ip));
        const char *remote_ip = user->conn.remote_ip == NULL ? NULL :
                p_strdup(user->pool, net_ip2addr(user->conn.remote_ip));
-
-       const char *auth_user, *auth_username, *auth_domain;
-       if (user->auth_user == NULL) {
-               auth_user = user->username;
-               auth_username = username;
-               auth_domain = domain;
-       } else {
-               auth_user = user->auth_user;
-               auth_username =
-                       p_strdup(user->pool, t_strcut(user->auth_user, '@'));
-               auth_domain = i_strchr_to_next(user->auth_user, '@');
-       }
-
        const char *local_port = "";
        const char *remote_port = "";
 
@@ -308,63 +304,51 @@ mail_user_var_expand_table(struct mail_user *user)
        }
 
        const struct var_expand_table stack_tab[] = {
-               { 'u', user->username, "user" },
-               { 'n', username, "username" },
-               { 'd', domain, "domain" },
-               { 's', user->service, "service" },
-               { 'l', local_ip, "local_ip" },
-               { 'r', remote_ip, "remote_ip" },
-               { '\0', local_port, "local_port" },
-               { '\0', remote_port, "remote_port" },
-               { '\0', user->session_id, "session" },
-               { '\0', auth_user, "auth_user" },
-               { '\0', auth_username, "auth_username" },
-               { '\0', auth_domain, "auth_domain" },
-               { '\0', user->set->hostname, "hostname" },
-               { '\0', user->conn.local_name, "local_name" },
-               { '\0', user->protocol, "protocol" },
+               { .key = "user", .value = user->username },
+               { .key = "service", .value = user->service },
+               { .key = "local_ip", .value = local_ip },
+               { .key = "remote_ip", .value = remote_ip },
+               { .key = "local_port", .value = local_port },
+               { .key = "remote_port", .value = remote_port },
+               { .key = "session", .value = user->session_id },
+               {
+                       .key = "auth_user",
+                       .value = user->auth_user != NULL ? user->auth_user :
+                                                          user->username
+               },
+               { .key = "hostname", .value = user->set->hostname },
+               { .key = "local_name", .value = user->conn.local_name },
+               { .key = "protocol", .value = user->protocol },
                /* default to owner being the same as user - these are
                   overridden by shared storage */
-               { '\0', user->username, "owner_user" },
-               { '\0', username, "owner_username" },
-               { '\0', domain, "owner_domain" },
-               { '\0', user->master_user, "master_user" },
+               { .key = "owner_user", .value = user->username },
+               { .key = "master_user", .value = user->master_user },
+               { .key = "home", .func = mail_user_var_expand_func_home },
+               { .key = "owner_home", .func = mail_user_var_expand_func_home },
                /* NOTE: keep this synced with imap-hibernate's
                   imap_client_var_expand_table() */
-               { '\0', NULL, NULL }
+               VAR_EXPAND_TABLE_END
        };
-       struct var_expand_table *tab;
 
-       tab = p_malloc(user->pool, sizeof(stack_tab));
-       memcpy(tab, stack_tab, sizeof(stack_tab));
-
-       user->var_expand_table = tab;
-       return user->var_expand_table;
-}
-
-static int
-mail_user_var_expand_func_home(const char *data ATTR_UNUSED, void *context,
-                              const char **value_r, const char **error_r)
-{
-       struct mail_user *user = context;
+       struct var_expand_params *params =
+               p_new(user->pool, struct var_expand_params, 1);
+       params->table = p_memdup(user->pool, stack_tab, sizeof(stack_tab));
+       params->providers = mail_user_var_expand_func_table;
+       params->context = user;
+       params->event = user->event;
 
-       if (mail_user_get_home(user, value_r) <= 0) {
-               *error_r = "Setting used home directory (%h) but there is no "
-                       "mail_home and userdb didn't return it";
-               return -1;
-       }
-       return 1;
+       user->var_expand_params = params;
+       return user->var_expand_params;
 }
 
 static int
-mail_user_var_expand_func_userdb(const char *data, void *context,
-                                const char **value_r,
-                                const char **error_r ATTR_UNUSED)
+mail_user_var_expand_func_userdb(const char *data, const char **value_r,
+                                void *context, const char **error_r ATTR_UNUSED)
 {
        struct mail_user *user = context;
 
        *value_r = mail_storage_service_fields_var_expand(data, user->userdb_fields);
-       return 1;
+       return 0;
 }
 
 void mail_user_set_home(struct mail_user *user, const char *home)
@@ -828,14 +812,11 @@ mail_user_get_dict_op_settings(struct mail_user *user)
        return user->dict_op_set;
 }
 
-static const struct var_expand_func_table mail_user_var_expand_func_table_arr[] = {
-       { "h", mail_user_var_expand_func_home },
-       { "home", mail_user_var_expand_func_home },
+static const struct var_expand_provider mail_user_var_expand_func_table_arr[] = {
        /* default to owner_home being the same as user's home - this is
           overridden by shared storage */
-       { "owner_home", mail_user_var_expand_func_home },
        { "userdb", mail_user_var_expand_func_userdb },
        { NULL, NULL }
 };
-const struct var_expand_func_table *mail_user_var_expand_func_table =
+const struct var_expand_provider *mail_user_var_expand_func_table =
        mail_user_var_expand_func_table_arr;
index b3a908bebfbbc279116ad1887431a669707e981b..e3577b8a2fd7188956453398d00abd3857c5731a 100644 (file)
@@ -57,7 +57,7 @@ struct mail_user {
           this stays the same after IMAP client is hibernated and restored. */
        time_t session_create_time;
 
-       const struct var_expand_table *var_expand_table;
+       const struct var_expand_params_new *var_expand_params;
        /* If non-NULL, fail the user initialization with this error.
           This could be set by plugins that need to fail the initialization. */
        const char *error;
@@ -123,7 +123,7 @@ union mail_user_module_context {
 };
 extern struct mail_user_module_register mail_user_module_register;
 extern struct auth_master_connection *mail_user_auth_master_conn;
-extern const struct var_expand_func_table *mail_user_var_expand_func_table;
+extern const struct var_expand_provider *mail_user_var_expand_func_table;
 
 struct mail_user *
 mail_user_alloc(struct mail_storage_service_user *service_user);
@@ -146,8 +146,8 @@ struct mail_user *mail_user_find(struct mail_user *user, const char *name);
 void mail_user_set_vars(struct mail_user *user, const char *service,
                        const struct mail_user_connection_data *conn);
 /* Return %variable expansion table for the user. */
-const struct var_expand_table *
-mail_user_var_expand_table(struct mail_user *user);
+const struct var_expand_params_new *
+mail_user_var_expand_params(struct mail_user *user);
 
 /* Specify the user's home directory. This should be called also with home=NULL
    when it's known that the user doesn't have a home directory to avoid the
index c7dfed676023b51ed13bc49d020df4b2a8a02317..fb75ad7779be3a666d3e0938d3deb464eee161e2 100644 (file)
@@ -4,7 +4,6 @@
 #include "str.h"
 #include "istream.h"
 #include "array.h"
-#include "var-expand.h"
 #include "dlua-script.h"
 #include "dlua-script-private.h"
 #include "mail-storage.h"
index 19327ba0a475964ca3e1a82c817143832b11bdb3..72823aca1136c8e1db1f09ba3212b073e74c1f06 100644 (file)
@@ -4,7 +4,6 @@
 #include "str.h"
 #include "istream.h"
 #include "array.h"
-#include "var-expand.h"
 #include "mail-storage.h"
 #include "mailbox-attribute.h"
 #include "mail-storage-lua.h"
index 9d56a9cc8d45c46ae75671caea2aa9b1f5a034d0..e2b28409c96e390113c8a24cb963d6cd71bd1814 100644 (file)
@@ -122,12 +122,11 @@ static void client_read_settings(struct client *client, bool ssl)
        client->raw_mail_user =
                raw_storage_create_from_set(storage_service, client->set_instance);
 
-       struct var_expand_params params = {
-               .table = mail_storage_service_get_var_expand_table(storage_service, &input),
-       };
+       const struct var_expand_params *params =
+               mail_storage_service_get_var_expand_params(storage_service, &input);
 
        struct event *event = event_create(client->event);
-       event_set_ptr(event, SETTINGS_EVENT_VAR_EXPAND_PARAMS, &params);
+       event_set_ptr(event, SETTINGS_EVENT_VAR_EXPAND_PARAMS, (void *)params);
        if (settings_get(event, &lda_setting_parser_info, 0,
                         &client->lda_set, &error) < 0 ||
            settings_get(event, &lmtp_setting_parser_info, 0,