#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"
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)
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) {
/* 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)
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);
}
#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"
} 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;
}
}
} 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;
}
}
} 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);