Mercurial > dovecot > original-hg > dovecot-1.2
changeset 2976:96a4ab34c8f1 HEAD
Added pop3_uidl_format setting.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 15 Dec 2004 22:05:15 +0200 |
parents | c59fd95ad3ee |
children | 4a6788997812 |
files | dovecot-example.conf src/lib-storage/index/index-mail.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/mail-storage.h src/master/mail-process.c src/master/master-settings.c src/master/master-settings.h src/pop3/client.c src/pop3/client.h src/pop3/commands.c src/pop3/common.h src/pop3/main.c |
diffstat | 12 files changed, 126 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Wed Dec 15 21:31:06 2004 +0200 +++ b/dovecot-example.conf Wed Dec 15 22:05:15 2004 +0200 @@ -444,6 +444,25 @@ # from new ones. Some clients still wish to use this though. Enabling this # makes RSET command clear all \Seen flags from messages. #pop3_enable_last = no + + # POP3 UIDL format to use. You can use following variables: + # + # %v - Mailbox UIDVALIDITY + # %u - Mail UID + # %m - MD5 sum of the mailbox headers in hex (mbox only) + # + # If you want UIDL compatibility with other POP3 servers, use: + # UW's ipop3d : %08Xv%08Xu + # Courier version 0 : (maildir filename, not supported) + # Courier version 1 : %u + # Courier version 2 : %v-%u + # Cyrus (old) : %u + # Cyrus (new) : %v.%u + # + # Note that Outlook 2003 seems to have problems with %v.%u format which is + # Dovecot's default, so if you're building a new server it would be a good + # idea to change this. %08Xu%08Xv should be pretty fail-safe. + #pop3_uidl_format = %v.%u # Support for dynamically loadable modules. #mail_use_modules = no
--- a/src/lib-storage/index/index-mail.c Wed Dec 15 21:31:06 2004 +0200 +++ b/src/lib-storage/index/index-mail.c Wed Dec 15 22:05:15 2004 +0200 @@ -3,6 +3,7 @@ #include "lib.h" #include "buffer.h" #include "istream.h" +#include "hex-binary.h" #include "str.h" #include "message-date.h" #include "message-part-serialize.h" @@ -518,6 +519,7 @@ struct index_mail_data *data = &mail->data; struct mail_cache_field *cache_fields = mail->ibox->cache_fields; string_t *str; + const void *ext_data; switch (field) { case MAIL_FETCH_IMAP_BODY: @@ -579,13 +581,16 @@ return data->envelope; case MAIL_FETCH_FROM_ENVELOPE: return NULL; - case MAIL_FETCH_UID_STRING: - if (data->uid_string == NULL) { - data->uid_string = - p_strdup_printf(mail->pool, "%u.%u", - mail->uid_validity, _mail->uid); + case MAIL_FETCH_HEADER_MD5: + if (mail_index_lookup_ext(mail->trans->trans_view, data->seq, + mail->ibox->md5hdr_ext_idx, + &ext_data) < 0) { + mail_storage_set_index_error(mail->ibox); + return NULL; } - return data->uid_string; + if (ext_data == NULL) + return NULL; + return binary_to_hex(ext_data, 16); default: i_unreached(); return NULL;
--- a/src/lib-storage/index/mbox/mbox-storage.c Wed Dec 15 21:31:06 2004 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.c Wed Dec 15 22:05:15 2004 +0200 @@ -417,6 +417,8 @@ ibox->md5hdr_ext_idx = mail_index_ext_register(ibox->index, "header-md5", 0, 16, 1); + if ((flags & MAILBOX_OPEN_KEEP_HEADER_MD5) != 0) + ibox->mbox_save_md5 = TRUE; if (access(path, R_OK|W_OK) < 0) { if (errno < EACCES)
--- a/src/lib-storage/mail-storage.h Wed Dec 15 21:31:06 2004 +0200 +++ b/src/lib-storage/mail-storage.h Wed Dec 15 22:05:15 2004 +0200 @@ -8,7 +8,8 @@ enum mailbox_open_flags { MAILBOX_OPEN_READONLY = 0x01, MAILBOX_OPEN_FAST = 0x02, - MAILBOX_OPEN_KEEP_RECENT = 0x04 + MAILBOX_OPEN_KEEP_RECENT = 0x04, + MAILBOX_OPEN_KEEP_HEADER_MD5 = 0x04 }; enum mailbox_list_flags { @@ -82,7 +83,7 @@ MAIL_FETCH_IMAP_BODYSTRUCTURE = 0x00002000, MAIL_FETCH_IMAP_ENVELOPE = 0x00004000, MAIL_FETCH_FROM_ENVELOPE = 0x00008000, - MAIL_FETCH_UID_STRING = 0x00010000 + MAIL_FETCH_HEADER_MD5 = 0x00010000 }; enum mailbox_sync_flags {
--- a/src/master/mail-process.c Wed Dec 15 21:31:06 2004 +0200 +++ b/src/master/mail-process.c Wed Dec 15 22:05:15 2004 +0200 @@ -197,6 +197,8 @@ set->imap_capability, NULL)); env_put(t_strconcat("IMAP_CLIENT_WORKAROUNDS=", set->imap_client_workarounds, NULL)); + env_put(t_strconcat("POP3_UIDL_FORMAT=", + set->pop3_uidl_format, NULL)); env_put(t_strconcat("POP3_CLIENT_WORKAROUNDS=", set->pop3_client_workarounds, NULL));
--- a/src/master/master-settings.c Wed Dec 15 21:31:06 2004 +0200 +++ b/src/master/master-settings.c Wed Dec 15 22:05:15 2004 +0200 @@ -125,6 +125,7 @@ /* pop3 */ DEF(SET_BOOL, pop3_no_flag_updates), DEF(SET_BOOL, pop3_enable_last), + DEF(SET_STR, pop3_uidl_format), DEF(SET_STR, pop3_client_workarounds), { 0, NULL, 0 } @@ -296,6 +297,7 @@ /* pop3 */ MEMBER(pop3_no_flag_updates) FALSE, MEMBER(pop3_enable_last) FALSE, + MEMBER(pop3_uidl_format) "%v.%u", MEMBER(pop3_client_workarounds) NULL, /* .. */
--- a/src/master/master-settings.h Wed Dec 15 21:31:06 2004 +0200 +++ b/src/master/master-settings.h Wed Dec 15 22:05:15 2004 +0200 @@ -96,6 +96,7 @@ /* pop3 */ int pop3_no_flag_updates; int pop3_enable_last; + const char *pop3_uidl_format; const char *pop3_client_workarounds; /* .. */
--- a/src/pop3/client.c Wed Dec 15 21:31:06 2004 +0200 +++ b/src/pop3/client.c Wed Dec 15 22:05:15 2004 +0200 @@ -37,16 +37,15 @@ static void client_input(void *context); static int client_output(void *context); -static int sync_mailbox(struct mailbox *box) +static int sync_mailbox(struct mailbox *box, struct mailbox_status *status) { struct mailbox_sync_context *ctx; struct mailbox_sync_rec sync_rec; - struct mailbox_status status; ctx = mailbox_sync_init(box, MAILBOX_SYNC_FLAG_FULL_READ); while (mailbox_sync_next(ctx, &sync_rec) > 0) ; - return mailbox_sync_deinit(ctx, &status); + return mailbox_sync_deinit(ctx, status); } static int init_mailbox(struct client *client) @@ -54,6 +53,7 @@ struct mail_search_arg search_arg; struct mailbox_transaction_context *t; struct mail_search_context *ctx; + struct mailbox_status status; struct mail *mail; buffer_t *message_sizes_buf; int i, failed; @@ -64,10 +64,11 @@ search_arg.type = SEARCH_ALL; for (i = 0; i < 2; i++) { - if (sync_mailbox(client->mailbox) < 0) { + if (sync_mailbox(client->mailbox, &status) < 0) { client_send_storage_error(client); break; } + client->uid_validity = status.uidvalidity; t = mailbox_transaction_begin(client->mailbox, FALSE); ctx = mailbox_search_init(t, NULL, &search_arg, NULL, @@ -152,6 +153,8 @@ flags = 0; if (no_flag_updates) flags |= MAILBOX_OPEN_KEEP_RECENT; + if ((uidl_keymask & UIDL_MD5) != 0) + flags |= MAILBOX_OPEN_KEEP_HEADER_MD5; client->mailbox = mailbox_open(storage, "INBOX", flags); if (client->mailbox == NULL) { i_error("Couldn't open INBOX: %s",
--- a/src/pop3/client.h Wed Dec 15 21:31:06 2004 +0200 +++ b/src/pop3/client.h Wed Dec 15 22:05:15 2004 +0200 @@ -22,6 +22,7 @@ time_t last_input, last_output; unsigned int bad_counter; + unsigned int uid_validity; unsigned int messages_count; unsigned int deleted_count; uoff_t *message_sizes;
--- a/src/pop3/commands.c Wed Dec 15 21:31:06 2004 +0200 +++ b/src/pop3/commands.c Wed Dec 15 22:05:15 2004 +0200 @@ -4,6 +4,7 @@ #include "istream.h" #include "ostream.h" #include "str.h" +#include "var-expand.h" #include "message-size.h" #include "mail-storage.h" #include "mail-search.h" @@ -478,10 +479,23 @@ static int list_uids_iter(struct client *client, struct cmd_uidl_context *ctx) { + static struct var_expand_table static_tab[] = { + { 'v', NULL }, + { 'u', NULL }, + { 'm', NULL }, + { '\0', NULL } + }; + struct var_expand_table *tab; struct mail *mail; - const char *uid_str; + string_t *str; int ret, found = FALSE; + tab = t_malloc(sizeof(static_tab)); + memcpy(tab, static_tab, sizeof(static_tab)); + tab[0].value = t_strdup_printf("%u", client->uid_validity); + + str = str_new(default_pool, 128); + while ((mail = mailbox_search_next(ctx->search_ctx)) != NULL) { if (client->deleted) { uint32_t idx = mail->seq - 1; @@ -489,21 +503,34 @@ (1 << (idx % CHAR_BIT))) continue; } - - uid_str = mail->get_special(mail, MAIL_FETCH_UID_STRING); found = TRUE; - ret = client_send_line(client, ctx->message == 0 ? - "%u %s" : "+OK %u %s", - mail->seq, uid_str); + t_push(); + if ((uidl_keymask & UIDL_UID) != 0) + tab[1].value = dec2str(mail->uid); + if ((uidl_keymask & UIDL_MD5) != 0) { + tab[2].value = + mail->get_special(mail, MAIL_FETCH_HEADER_MD5); + } + + str_truncate(str, 0); + str_printfa(str, ctx->message == 0 ? "%u " : "+OK %u ", + mail->seq); + var_expand(str, uidl_format, tab); + + ret = client_send_line(client, "%s", str_c(str)); + t_pop(); + if (ret < 0) break; if (ret == 0 && ctx->message == 0) { /* output is being buffered, continue when there's more space */ + str_free(str); return 0; } } + str_free(str); /* finished */ (void)mailbox_search_deinit(ctx->search_ctx); @@ -527,6 +554,7 @@ cmd_uidl_init(struct client *client, unsigned int message) { struct cmd_uidl_context *ctx; + enum mail_fetch_field wanted_fields; ctx = i_new(struct cmd_uidl_context, 1); @@ -539,8 +567,13 @@ ctx->search_arg.value.seqset = &ctx->seqset; } + wanted_fields = 0; + if ((uidl_keymask & UIDL_MD5) != 0) + wanted_fields |= MAIL_FETCH_HEADER_MD5; + ctx->search_ctx = mailbox_search_init(client->trans, NULL, - &ctx->search_arg, NULL, 0, NULL); + &ctx->search_arg, NULL, + wanted_fields, NULL); if (message == 0) { client->cmd = cmd_uidl_callback; client->cmd_context = ctx;
--- a/src/pop3/common.h Wed Dec 15 21:31:06 2004 +0200 +++ b/src/pop3/common.h Wed Dec 15 22:05:15 2004 +0200 @@ -9,9 +9,17 @@ WORKAROUND_OE_NS_EOH = 0x02 }; +enum uidl_keys { + UIDL_UIDVALIDITY = 0x01, + UIDL_UID = 0x02, + UIDL_MD5 = 0x04 +}; + extern struct ioloop *ioloop; extern enum client_workarounds client_workarounds; extern int enable_last_command, no_flag_updates; +extern const char *uidl_format; +extern enum uidl_keys uidl_keymask; extern void (*hook_mail_storage_created)(struct mail_storage **storage); extern void (*hook_client_created)(struct client **client);
--- a/src/pop3/main.c Wed Dec 15 21:31:06 2004 +0200 +++ b/src/pop3/main.c Wed Dec 15 22:05:15 2004 +0200 @@ -9,6 +9,7 @@ #include "process-title.h" #include "randgen.h" #include "module-dir.h" +#include "var-expand.h" #include "mail-storage.h" #include <stdio.h> @@ -40,6 +41,8 @@ enum client_workarounds client_workarounds = 0; int enable_last_command = FALSE; int no_flag_updates = FALSE; +const char *uidl_format; +enum uidl_keys uidl_keymask; static void sig_quit(int signo __attr_unused__) { @@ -68,6 +71,28 @@ } } +static enum uidl_keys parse_uidl_keymask(const char *format) +{ + 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; + } + } + } + return mask; +} + static void open_logfile(void) { const char *user; @@ -139,6 +164,11 @@ enable_last_command = getenv("POP3_ENABLE_LAST") != NULL; no_flag_updates = getenv("POP3_NO_FLAG_UPDATES") != NULL; + uidl_format = getenv("POP3_UIDL_FORMAT"); + if (uidl_format == NULL) + uidl_format = "%v.%u"; + uidl_keymask = parse_uidl_keymask(uidl_format); + storage = mail_storage_create_with_data(mail, getenv("USER")); if (storage == NULL) { /* failed */