From: Aki Tuomi Date: Thu, 29 Aug 2024 10:42:40 +0000 (+0300) Subject: pop3: Use new var_expand X-Git-Tag: 2.4.0~316 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cca2c7a394b590f71b706b97e28fd60090d1f76b;p=thirdparty%2Fdovecot%2Fcore.git pop3: Use new var_expand --- diff --git a/src/lib-storage/mail-storage-settings.c b/src/lib-storage/mail-storage-settings.c index 0a03635ba4..18c9dff2ea 100644 --- a/src/lib-storage/mail-storage-settings.c +++ b/src/lib-storage/mail-storage-settings.c @@ -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 = "%{uid|number|hex(8)}%{uidvalidity|number|hex(8)}", + .pop3_uidl_format = "%{uid | hex(8)}%{uidvalidity | hex(8)}", .recipient_delimiter = "+", diff --git a/src/pop3/pop3-client.c b/src/pop3/pop3-client.c index 33e695ff9a..d2539ad322 100644 --- a/src/pop3/pop3-client.c +++ b/src/pop3/pop3-client.c @@ -14,8 +14,8 @@ #include "llist.h" #include "hostpid.h" #include "file-dotlock.h" -#include "var-expand.h" #include "settings.h" +#include "var-expand-new.h" #include "master-service.h" #include "mail-storage.h" #include "mail-storage-service.h" @@ -301,32 +301,36 @@ static int init_mailbox(struct client *client, const char **error_r) return -1; } -static enum uidl_keys parse_uidl_keymask(const char *format) +static int parse_uidl_keymask(const char *format, enum uidl_keys *keys, + const char **error_r) { enum uidl_keys mask = 0; - - for (; *format != '\0'; format++) { - if (format[0] == '%' && format[1] != '\0') { - switch (var_get_key(++format)) { - case 'v': - mask |= UIDL_UIDVALIDITY; - break; - case 'u': - mask |= UIDL_UID; - break; - case 'm': - mask |= UIDL_MD5; - break; - case 'f': - mask |= UIDL_FILE_NAME; - break; - case 'g': - mask |= UIDL_GUID; - break; - } + struct var_expand_program *prog; + if (var_expand_program_create(format, &prog, error_r) < 0) + return -1; + const char *const *vars = var_expand_program_variables(prog); + int ret = 0; + + for (; *vars != NULL; vars++) { + if (strcmp(*vars, "uidvalidity") == 0) + mask |= UIDL_UIDVALIDITY; + else if (strcmp(*vars, "uid") == 0) + mask |= UIDL_UID; + else if (strcmp(*vars, "md5") == 0) + mask |= UIDL_MD5; + else if (strcmp(*vars, "filename") == 0) + mask |= UIDL_FILE_NAME; + else if (strcmp(*vars, "guid") == 0) + mask |= UIDL_GUID; + else { + *error_r = t_strdup_printf("Invalid key %%{%s}", *vars); + ret = -1; + break; } } - return mask; + if (ret == 0) + *keys = mask; + return ret; } static void pop3_lock_session_refresh(struct client *client) @@ -416,7 +420,7 @@ struct client *client_create(int fd_in, int fd_out, client->user = user; - if (var_has_key(set->pop3_logout_format, 'u', "uidl_change")) { + if (set->parsed_want_uidl_change) { /* logging uidl_change. we need hashes of the UIDLs */ client->message_uidls_save = TRUE; } else if (strcmp(set->pop3_uidl_duplicates, "allow") != 0) { @@ -451,10 +455,11 @@ int client_init_mailbox(struct client *client, const char **error_r) /* refresh proctitle before a potentially long-running init_mailbox() */ pop3_refresh_proctitle(); - client->uidl_keymask = - parse_uidl_keymask(client->mail_set->pop3_uidl_format); + if (parse_uidl_keymask(client->mail_set->pop3_uidl_format, + &client->uidl_keymask, &errmsg) < 0) + i_fatal("Invalid pop3_uidl_format: %s", errmsg); if (client->uidl_keymask == 0) - i_fatal("Invalid pop3_uidl_format"); + i_fatal("Invalid pop3_uidl_format: Empty format"); flags = MAILBOX_FLAG_POP3_SESSION; if (!client->set->pop3_no_flag_updates) @@ -525,47 +530,55 @@ static const char *client_build_uidl_change_string(struct client *client) static const char *client_stats(struct client *client) { - const char *uidl_change = ""; - if (var_has_key(client->set->pop3_logout_format, - 'u', "uidl_change")) + const char *error, *uidl_change = ""; + + if (client->set->parsed_want_uidl_change) uidl_change = client_build_uidl_change_string(client); const struct var_expand_table logout_tab[] = { - { 'p', dec2str(client->top_bytes), "top_bytes" }, - { 't', dec2str(client->top_count), "top_count" }, - { 'b', dec2str(client->retr_bytes), "retr_bytes" }, - { 'r', dec2str(client->retr_count), "retr_count" }, - { 'd', !client->delete_success ? "0" : - dec2str(client->deleted_count), "deleted_count" }, - { 'm', dec2str(client->messages_count), "message_count" }, - { 's', dec2str(client->total_size), "message_bytes" }, - { 'i', dec2str(i_stream_get_absolute_offset(client->input)), - "input" }, - { 'o', dec2str(client->output->offset), "output" }, - { 'u', uidl_change, "uidl_change" }, - { '\0', !client->delete_success ? "0" : - dec2str(client->deleted_size), "deleted_bytes" }, - { '\0', NULL, NULL } + { .key = "top_bytes", .value = dec2str(client->top_bytes) }, + { .key = "top_count", .value = dec2str(client->top_count) }, + { .key = "retr_bytes", .value = dec2str(client->retr_bytes) }, + { .key = "retr_count", .value = dec2str(client->retr_count) }, + { .key = "deleted_count", + .value = !client->delete_success ? "0" : + dec2str(client->deleted_count) }, + { .key = "message_count", .value = dec2str(client->messages_count) }, + { .key = "message_bytes", .value = dec2str(client->total_size) }, + { .key = "input", + .value = dec2str(i_stream_get_absolute_offset(client->input)), }, + { .key = "output", .value = dec2str(client->output->offset) }, + { .key = "uidl_change", .value = uidl_change }, + { .key = "deleted_bytes", .value = !client->delete_success ? "0" : + dec2str(client->deleted_size) }, + VAR_EXPAND_TABLE_END + }; + + const struct var_expand_params *user_params = + mail_user_var_expand_params(client->user); + const struct var_expand_params params = { + .tables_arr = (const struct var_expand_table*[]) { + user_params->table, + logout_tab, + NULL + }, + .providers = user_params->providers, + .context = user_params->context, + .event = client->event, }; - const struct var_expand_table *user_tab = - mail_user_var_expand_table(client->user); - const struct var_expand_table *tab = - t_var_expand_merge_tables(logout_tab, user_tab); string_t *str; - const char *error; + + event_add_int(client->event, "net_in_bytes", i_stream_get_absolute_offset(client->input)); + event_add_int(client->event, "net_out_bytes", client->output->offset); str = t_str_new(128); - if (var_expand_with_funcs(str, client->set->pop3_logout_format, - tab, mail_user_var_expand_func_table, - client->user, &error) <= 0) { + if (var_expand_new(str, client->set->pop3_logout_format, + ¶ms, &error) < 0) { e_error(client->event, "Failed to expand pop3_logout_format=%s: %s", client->set->pop3_logout_format, error); } - event_add_int(client->event, "net_in_bytes", i_stream_get_absolute_offset(client->input)); - event_add_int(client->event, "net_out_bytes", client->output->offset); - return str_c(str); } diff --git a/src/pop3/pop3-commands.c b/src/pop3/pop3-commands.c index 4e7718e6dd..8c6d9b3b98 100644 --- a/src/pop3/pop3-commands.c +++ b/src/pop3/pop3-commands.c @@ -7,7 +7,7 @@ #include "hash.h" #include "str.h" #include "strfuncs.h" -#include "var-expand.h" +#include "var-expand-new.h" #include "message-size.h" #include "mail-storage.h" #include "mail-storage-settings.h" @@ -635,7 +635,7 @@ pop3_get_uid(struct client *client, struct mail *mail, string_t *str, } else if (hdr_md5[0] == '\0') { e_error(client->event, "UIDL: Header MD5 not found " - "(pop3_uidl_format=%%m not supported by storage?)"); + "(pop3_uidl_format=%%{md5} not supported by storage?)"); return -1; } } @@ -649,7 +649,7 @@ pop3_get_uid(struct client *client, struct mail *mail, string_t *str, } else if (filename[0] == '\0') { e_error(client->event, "UIDL: File name not found " - "(pop3_uidl_format=%%f not supported by storage?)"); + "(pop3_uidl_format=%%{filename} not supported by storage?)"); return -1; } } @@ -663,23 +663,25 @@ pop3_get_uid(struct client *client, struct mail *mail, string_t *str, } else if (guid[0] == '\0') { e_error(client->event, "UIDL: Message GUID not found " - "(pop3_uidl_format=%%g not supported by storage?)"); + "(pop3_uidl_format=%%{guid} not supported by storage?)"); return -1; } } - const struct var_expand_table tab[] = { - { 'v', dec2str(client->uid_validity), "uidvalidity" }, - { 'u', uid_str, "uid" }, - { 'm', hdr_md5, "md5" }, - { 'f', filename, "filename" }, - { 'g', guid, "guid" }, - { '\0', NULL, NULL } + const struct var_expand_params params = { + .table = (const struct var_expand_table[]) { + { .key = "uidvalidity", .value = dec2str(client->uid_validity) }, + { .key = "uid", .value = uid_str }, + { .key = "md5", .value = hdr_md5 }, + { .key = "filename", .value = filename }, + { .key = "guid", .value = guid }, + VAR_EXPAND_TABLE_END + }, }; const char *error; - if (var_expand_with_table(str, client->mail_set->pop3_uidl_format, - tab, &error) <= 0) { + if (var_expand_new(str, client->mail_set->pop3_uidl_format, + ¶ms, &error) < 0) { e_error(client->event, "UIDL: Failed to expand pop3_uidl_format=%s: %s", client->mail_set->pop3_uidl_format, error); diff --git a/src/pop3/pop3-settings.c b/src/pop3/pop3-settings.c index 8cf867ea2d..a2cf9b9978 100644 --- a/src/pop3/pop3-settings.c +++ b/src/pop3/pop3-settings.c @@ -6,6 +6,7 @@ #include "service-settings.h" #include "mail-storage-settings.h" #include "pop3-settings.h" +#include "var-expand-new.h" #include @@ -82,7 +83,11 @@ static const struct pop3_settings pop3_default_settings = { .pop3_lock_session = FALSE, .pop3_fast_size_lookups = FALSE, .pop3_client_workarounds = ARRAY_INIT, - .pop3_logout_format = "top=%t/%p, retr=%r/%b, del=%d/%m, size=%s", + .pop3_logout_format = + "top=%{top_count}/%{top_bytes}, " + "retr=%{retr_count}/%{retr_bytes}, " + "del=%{deleted_count}/%{deleted_bytes}, " + "size=%{message_bytes}", .pop3_uidl_duplicates = "allow:rename", .pop3_deleted_flag = "", .pop3_delete_type = "default:expunge:flag" @@ -163,6 +168,17 @@ pop3_settings_verify(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) set->pop3_delete_type); return FALSE; } + + struct var_expand_program *prog; + const char *error; + if (var_expand_program_create(set->pop3_logout_format, &prog, &error) < 0) { + *error_r = t_strdup_printf("Invalid pop3_logout_format: %s", error); + return FALSE; + } + const char *const *vars = var_expand_program_variables(prog); + set->parsed_want_uidl_change = str_array_find(vars, "uidl_change"); + var_expand_program_free(&prog); + return TRUE; } /* */ diff --git a/src/pop3/pop3-settings.h b/src/pop3/pop3-settings.h index adb4244e3f..527153dee6 100644 --- a/src/pop3/pop3-settings.h +++ b/src/pop3/pop3-settings.h @@ -34,6 +34,7 @@ struct pop3_settings { enum pop3_client_workarounds parsed_workarounds; enum pop3_delete_type parsed_delete_type; + bool parsed_want_uidl_change; }; extern const struct setting_parser_info pop3_setting_parser_info;