Mercurial > dovecot > core-2.2
changeset 12596:d75d4841c890
imapc: Implemented more methods.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 24 Jan 2011 00:00:02 +0200 |
parents | 5d97dfa9d86c |
children | a349c50cddaa |
files | src/lib-storage/index/imapc/imapc-client.c src/lib-storage/index/imapc/imapc-connection.c src/lib-storage/index/imapc/imapc-connection.h src/lib-storage/index/imapc/imapc-storage.c src/lib-storage/index/imapc/imapc-storage.h |
diffstat | 5 files changed, 91 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/imapc/imapc-client.c Sun Jan 23 23:32:52 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-client.c Mon Jan 24 00:00:02 2011 +0200 @@ -179,6 +179,7 @@ } } + imapc_connection_unselect(box); imapc_seqmap_deinit(&box->seqmap); i_free(box); }
--- a/src/lib-storage/index/imapc/imapc-connection.c Sun Jan 23 23:32:52 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-connection.c Mon Jan 24 00:00:02 2011 +0200 @@ -1022,6 +1022,15 @@ imapc_connection_cmdf(conn, callback, context, "SELECT %s", name); } +void imapc_connection_unselect(struct imapc_client_mailbox *box) +{ + i_assert(box->conn->selected_box == box || + box->conn->selecting_box == box); + + box->conn->selected_box = NULL; + box->conn->selecting_box = NULL; +} + static void imapc_connection_idle_callback(const struct imapc_command_reply *reply ATTR_UNUSED, void *context)
--- a/src/lib-storage/index/imapc/imapc-connection.h Sun Jan 23 23:32:52 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-connection.h Mon Jan 24 00:00:02 2011 +0200 @@ -35,6 +35,7 @@ ATTR_FORMAT(4, 0); void imapc_connection_select(struct imapc_client_mailbox *box, const char *name, imapc_command_callback_t *callback, void *context); +void imapc_connection_unselect(struct imapc_client_mailbox *box); enum imapc_connection_state imapc_connection_get_state(struct imapc_connection *conn);
--- a/src/lib-storage/index/imapc/imapc-storage.c Sun Jan 23 23:32:52 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.c Mon Jan 24 00:00:02 2011 +0200 @@ -3,6 +3,7 @@ #include "lib.h" #include "ioloop.h" #include "str.h" +#include "imap-arg.h" #include "imap-resp-code.h" #include "mail-copy.h" #include "index-mail.h" @@ -18,12 +19,6 @@ int ret; }; -struct imapc_status_context { - struct imapc_mailbox *mbox; - struct mailbox_status *status; - int ret; -}; - struct imapc_resp_code_map { const char *code; enum mail_error error; @@ -52,6 +47,9 @@ { IMAP_RESP_CODE_NONEXISTENT, MAIL_ERROR_NOTFOUND } }; +static void imapc_untagged_status(const struct imapc_untagged_reply *reply, + struct imapc_storage *storage); + static bool imap_resp_text_code_parse(const char *str, enum mail_error *error_r) { @@ -167,11 +165,26 @@ { struct imapc_storage *storage = (struct imapc_storage *)_storage; struct imapc_client_settings set; + const char *port; memset(&set, 0, sizeof(set)); set.host = ns->list->set.root_dir; - set.port = 143; - set.username = _storage->user->username; + + port = mail_user_plugin_getenv(_storage->user, "imapc_port"); + if (port == NULL) + set.port = 143; + else { + if (str_to_uint(port, &set.port) < 0 || + set.port == 0 || set.port >= 65536) { + *error_r = t_strdup_printf("Invalid port: %s", port); + return -1; + } + } + + set.username = mail_user_plugin_getenv(_storage->user, "imapc_user"); + if (set.username == NULL) + set.username = _storage->user->username; + set.password = mail_user_plugin_getenv(_storage->user, "pass"); if (set.password == NULL) { *error_r = "missing pass"; @@ -188,6 +201,8 @@ imapc_client_register_untagged(storage->client, imapc_storage_untagged_cb, storage); imapc_list_register_callbacks(storage->list); + imapc_storage_register_untagged(storage, "STATUS", + imapc_untagged_status); return 0; } @@ -343,6 +358,45 @@ return -1; } +static void imapc_untagged_status(const struct imapc_untagged_reply *reply, + struct imapc_storage *storage) +{ + struct mailbox_status *status; + const struct imap_arg *list; + const char *name, *key, *value; + uint32_t num; + unsigned int i; + + if (!imap_arg_get_astring(&reply->args[0], &name) || + !imap_arg_get_list(&reply->args[1], &list)) + return; + + if (storage->cur_status_box == NULL || + strcmp(storage->cur_status_box->box.name, name) != 0) + return; + + status = storage->cur_status; + for (i = 0; list[i].type != IMAP_ARG_EOL; i += 2) { + if (!imap_arg_get_atom(&list[i], &key) || + !imap_arg_get_atom(&list[i+1], &value) || + str_to_uint32(value, &num) < 0) + return; + + if (strcasecmp(key, "MESSAGES") == 0) + status->messages = num; + else if (strcasecmp(key, "RECENT") == 0) + status->recent = num; + else if (strcasecmp(key, "UIDNEXT") == 0) + status->uidnext = num; + else if (strcasecmp(key, "UIDVALIDITY") == 0) + status->uidvalidity = num; + else if (strcasecmp(key, "UNSEEN") == 0) + status->unseen = num; + else if (strcasecmp(key, "HIGHESTMODSEQ") == 0) + status->highest_modseq = num; + } +} + static void imapc_mailbox_get_selected_status(struct imapc_mailbox *mbox, enum mailbox_status_items items, struct mailbox_status *status_r) @@ -350,32 +404,12 @@ index_storage_get_status(&mbox->box, items, status_r); } -static void -imapc_mailbox_status_callback(const struct imapc_command_reply *reply, - void *context) -{ - struct imapc_status_context *ctx = context; - - if (reply->state == IMAPC_COMMAND_STATE_OK) - ctx->ret = 0; - else if (reply->state == IMAPC_COMMAND_STATE_NO) { - imapc_copy_error_from_reply(ctx->mbox->storage, - MAIL_ERROR_NOTFOUND, reply); - } else { - mail_storage_set_critical(ctx->mbox->box.storage, - "imapc: STATUS for mailbox '%s' failed: %s", - ctx->mbox->box.name, reply->text_full); - ctx->ret = -1; - } - imapc_client_stop(ctx->mbox->storage->client); -} - static int imapc_mailbox_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status_r) { struct imapc_mailbox *mbox = (struct imapc_mailbox *)box; - struct imapc_status_context ctx; + struct imapc_simple_context ctx; string_t *str; memset(status_r, 0, sizeof(*status_r)); @@ -413,22 +447,28 @@ return 0; } - ctx.mbox = mbox; - ctx.status = status_r; + ctx.storage = mbox->storage; + mbox->storage->cur_status_box = mbox; + mbox->storage->cur_status = status_r; imapc_client_cmdf(mbox->storage->client, - imapc_mailbox_status_callback, &ctx, + imapc_simple_callback, &ctx, "STATUS %s (%1s)", box->name, str_c(str)); imapc_client_run(mbox->storage->client); + mbox->storage->cur_status_box = NULL; + mbox->storage->cur_status = NULL; return ctx.ret; } static int imapc_mailbox_get_metadata(struct mailbox *box, - enum mailbox_metadata_items items ATTR_UNUSED, - struct mailbox_metadata *metadata_r ATTR_UNUSED) + enum mailbox_metadata_items items, + struct mailbox_metadata *metadata_r) { - mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE, - "Not supported"); - return -1; + if ((items & MAILBOX_METADATA_GUID) != 0) { + /* a bit ugly way to do this, but better than nothing for now. + FIXME: if indexes are enabled, keep this there. */ + mail_generate_guid_128_hash(box->name, metadata_r->guid); + } + return index_mailbox_get_metadata(box, items, metadata_r); } static void imapc_notify_changes(struct mailbox *box ATTR_UNUSED)
--- a/src/lib-storage/index/imapc/imapc-storage.h Sun Jan 23 23:32:52 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.h Mon Jan 24 00:00:02 2011 +0200 @@ -31,6 +31,9 @@ struct imapc_mailbox_list *list; struct imapc_client *client; + struct imapc_mailbox *cur_status_box; + struct mailbox_status *cur_status; + ARRAY_DEFINE(untagged_callbacks, struct imapc_storage_event_callback); };