imapc-storage.c revision 94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny/* Copyright (c) 2011 Dovecot authors, see the included COPYING file */
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "lib.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "ioloop.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "str.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "safe-mkstemp.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "imap-arg.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "imap-resp-code.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "imapc-mail.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "imapc-client.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "imapc-list.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "imapc-sync.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#include "imapc-storage.h"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny#define DNS_CLIENT_SOCKET_NAME "dns-client"
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zelenystruct imapc_open_context {
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny struct imapc_mailbox *mbox;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny int ret;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny};
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekstruct imapc_resp_code_map {
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny const char *code;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny enum mail_error error;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny};
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekextern struct mail_storage imapc_storage;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekextern struct mailbox imapc_mailbox;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březinastatic struct imapc_resp_code_map imapc_resp_code_map[] = {
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_UNAVAILABLE, MAIL_ERROR_TEMP },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_AUTHFAILED, MAIL_ERROR_PERM },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_AUTHZFAILED, MAIL_ERROR_PERM },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_EXPIRED, MAIL_ERROR_PERM },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_PRIVACYREQUIRED, MAIL_ERROR_PERM },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_CONTACTADMIN, MAIL_ERROR_PERM },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_NOPERM, MAIL_ERROR_PERM },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_INUSE, MAIL_ERROR_INUSE },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_EXPUNGEISSUED, MAIL_ERROR_EXPUNGED },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_CORRUPTION, MAIL_ERROR_TEMP },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina { IMAP_RESP_CODE_SERVERBUG, MAIL_ERROR_TEMP },
cf1a8af5556b1d8eab68802918c881ae1a0b89ebPavel Březina /* { IMAP_RESP_CODE_CLIENTBUG, 0 }, */
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce { IMAP_RESP_CODE_CANNOT, MAIL_ERROR_NOTPOSSIBLE },
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce { IMAP_RESP_CODE_LIMIT, MAIL_ERROR_NOTPOSSIBLE },
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce { IMAP_RESP_CODE_OVERQUOTA, MAIL_ERROR_NOSPACE },
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce { IMAP_RESP_CODE_ALREADYEXISTS, MAIL_ERROR_EXISTS },
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce { IMAP_RESP_CODE_NONEXISTENT, MAIL_ERROR_NOTFOUND }
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce};
1f800ebb0f190854b8296146174f3d696a426333Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorcestatic void imapc_untagged_status(const struct imapc_untagged_reply *reply,
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce struct imapc_storage *storage);
1f800ebb0f190854b8296146174f3d696a426333Simo Sorce
1f800ebb0f190854b8296146174f3d696a426333Simo Sorcestatic bool
07b92f78d1751d8a2a538a440e1fdb24c59021e0Pavel Březinaimap_resp_text_code_parse(const char *str, enum mail_error *error_r)
1f800ebb0f190854b8296146174f3d696a426333Simo Sorce{
1f800ebb0f190854b8296146174f3d696a426333Simo Sorce unsigned int i;
850ca620611f65115ee95e1d919be8443f95c14cLukas Slebodnik
1f800ebb0f190854b8296146174f3d696a426333Simo Sorce if (str == NULL)
850ca620611f65115ee95e1d919be8443f95c14cLukas Slebodnik return FALSE;
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce
1f800ebb0f190854b8296146174f3d696a426333Simo Sorce for (i = 0; i < N_ELEMENTS(imapc_resp_code_map); i++) {
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce if (strcmp(imapc_resp_code_map[i].code, str) == 0) {
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce *error_r = imapc_resp_code_map[i].error;
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce return TRUE;
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek }
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek }
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek return FALSE;
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek}
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozekstatic struct mail_storage *imapc_storage_alloc(void)
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek{
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek struct imapc_storage *storage;
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek pool_t pool;
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek pool = pool_alloconly_create("imapc storage", 512+256);
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek storage = p_new(pool, struct imapc_storage, 1);
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek storage->storage = imapc_storage;
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek storage->storage.pool = pool;
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek return &storage->storage;
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek}
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozekvoid imapc_copy_error_from_reply(struct imapc_storage *storage,
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek enum mail_error default_error,
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek const struct imapc_command_reply *reply)
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek{
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek enum mail_error error;
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek if (imap_resp_text_code_parse(reply->resp_text_key, &error)) {
33c865412732554ef255e93c4e7a58b0bce963c6Jakub Hrozek mail_storage_set_error(&storage->storage, error,
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce reply->text_without_resp);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce } else {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce mail_storage_set_error(&storage->storage, default_error,
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce reply->text_without_resp);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce}
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorcevoid imapc_simple_callback(const struct imapc_command_reply *reply,
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce void *context)
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce{
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce struct imapc_simple_context *ctx = context;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (reply->state == IMAPC_COMMAND_STATE_OK)
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce ctx->ret = 0;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce else if (reply->state == IMAPC_COMMAND_STATE_NO) {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce imapc_copy_error_from_reply(ctx->storage, MAIL_ERROR_PARAMS, reply);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce ctx->ret = -1;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce } else {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce mail_storage_set_critical(&ctx->storage->storage,
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce "imapc: Command failed: %s", reply->text_full);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce ctx->ret = -1;
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina }
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina imapc_client_stop(ctx->storage->client);
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina}
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březinavoid imapc_async_stop_callback(const struct imapc_command_reply *reply,
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina void *context)
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina{
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina struct imapc_storage *storage = context;
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina if (reply->state == IMAPC_COMMAND_STATE_OK)
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina ;
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina else if (reply->state == IMAPC_COMMAND_STATE_NO) {
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina imapc_copy_error_from_reply(storage, MAIL_ERROR_PARAMS, reply);
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina } else {
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina mail_storage_set_critical(&storage->storage,
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina "imapc: Command failed: %s", reply->text_full);
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina }
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina imapc_client_stop(storage->client);
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina}
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březinastatic void imapc_storage_untagged_cb(const struct imapc_untagged_reply *reply,
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina void *context)
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina{
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina struct imapc_storage *storage = context;
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina struct imapc_mailbox *mbox = reply->untagged_box_context;
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina const struct imapc_storage_event_callback *cb;
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina const struct imapc_mailbox_event_callback *mcb;
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina array_foreach(&storage->untagged_callbacks, cb) {
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina if (strcasecmp(reply->name, cb->name) == 0)
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina cb->callback(reply, storage);
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina }
e1f68731525116ce686ffcdc07ad3a14e4fb1cd7Pavel Březina
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina if (mbox == NULL)
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina return;
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina array_foreach(&mbox->untagged_callbacks, mcb) {
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina if (strcasecmp(reply->name, mcb->name) == 0)
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina mcb->callback(reply, mbox);
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina }
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina if (reply->resp_text_key != NULL) {
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina array_foreach(&mbox->resp_text_callbacks, mcb) {
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina if (strcasecmp(reply->resp_text_key, mcb->name) == 0)
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina mcb->callback(reply, mbox);
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina }
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina }
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina}
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březinastatic int
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březinaimapc_storage_create(struct mail_storage *_storage,
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina struct mail_namespace *ns,
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina const char **error_r)
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina{
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina struct imapc_storage *storage = (struct imapc_storage *)_storage;
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina struct imapc_client_settings set;
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina const char *port;
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina memset(&set, 0, sizeof(set));
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina set.host = ns->list->set.root_dir;
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina port = mail_user_plugin_getenv(_storage->user, "imapc_port");
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina if (port == NULL)
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina set.port = 143;
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina else {
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina if (str_to_uint(port, &set.port) < 0 ||
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina set.port == 0 || set.port >= 65536) {
0b81cc5d41ec6a1c58e610f402fd93a1fbda4affPavel Březina *error_r = t_strdup_printf("Invalid port: %s", port);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny return -1;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny }
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny }
b8dcd1216e5ea7065213c750a92dabfe01fa3b70Simo Sorce
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny set.username = mail_user_plugin_getenv(_storage->user, "imapc_user");
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose if (set.username == NULL)
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek set.username = _storage->user->username;
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny set.password = mail_user_plugin_getenv(_storage->user, "pass");
f91e4aacb78d33791efcd744000597d5254dac4bSimo Sorce if (set.password == NULL) {
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny *error_r = "missing pass";
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce return -1;
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce }
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce set.dns_client_socket_path =
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny t_strconcat(_storage->user->set->base_dir, "/",
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny DNS_CLIENT_SOCKET_NAME, NULL);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny storage->list = (struct imapc_mailbox_list *)ns->list;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny storage->list->storage = storage;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny storage->client = imapc_client_init(&set);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny p_array_init(&storage->untagged_callbacks, _storage->pool, 16);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny imapc_client_register_untagged(storage->client,
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny imapc_storage_untagged_cb, storage);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny imapc_list_register_callbacks(storage->list);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny imapc_storage_register_untagged(storage, "STATUS",
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny imapc_untagged_status);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny return 0;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny}
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zelenystatic void imapc_storage_destroy(struct mail_storage *_storage)
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny{
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny struct imapc_storage *storage = (struct imapc_storage *)_storage;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
d3f2fd9cb21cc10dce663a2f7d0deda07074e44eJan Zeleny imapc_client_deinit(&storage->client);
d3f2fd9cb21cc10dce663a2f7d0deda07074e44eJan Zeleny}
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zelenyvoid imapc_storage_register_untagged(struct imapc_storage *storage,
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny const char *name,
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny imapc_storage_callback_t *callback)
b8dcd1216e5ea7065213c750a92dabfe01fa3b70Simo Sorce{
b8dcd1216e5ea7065213c750a92dabfe01fa3b70Simo Sorce struct imapc_storage_event_callback *cb;
b8dcd1216e5ea7065213c750a92dabfe01fa3b70Simo Sorce
b8dcd1216e5ea7065213c750a92dabfe01fa3b70Simo Sorce cb = array_append_space(&storage->untagged_callbacks);
b8dcd1216e5ea7065213c750a92dabfe01fa3b70Simo Sorce cb->name = p_strdup(storage->storage.pool, name);
b8dcd1216e5ea7065213c750a92dabfe01fa3b70Simo Sorce cb->callback = callback;
b8dcd1216e5ea7065213c750a92dabfe01fa3b70Simo Sorce}
b8dcd1216e5ea7065213c750a92dabfe01fa3b70Simo Sorce
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zelenystatic void
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zelenyimapc_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny struct mailbox_list_settings *set)
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny{
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny set->layout = MAILBOX_LIST_NAME_IMAPC;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny}
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zelenystatic struct mailbox *
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zelenyimapc_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny const char *vname, enum mailbox_flags flags)
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny{
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny struct imapc_mailbox *mbox;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny struct index_mailbox_context *ibox;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny pool_t pool;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny flags |= MAILBOX_FLAG_NO_INDEX_FILES;
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek
58fd3aa25c5292bc67432647ab7e5059439fcc6dSimo Sorce pool = pool_alloconly_create("imapc mailbox", 1024*3);
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose mbox = p_new(pool, struct imapc_mailbox, 1);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny mbox->box = imapc_mailbox;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny mbox->box.pool = pool;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny mbox->box.storage = storage;
bf8cce77a35cb0a3cdb0d21fb9c39b7b6372bc11Jan Zeleny mbox->box.list = list;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny mbox->box.mail_vfuncs = &imapc_mail_vfuncs;
ac7a7ee3d1e138818a1ed78758f7dd3c3306a56bSumit Bose
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny index_storage_mailbox_alloc(&mbox->box, vname, flags, NULL);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny ibox->save_commit_pre = imapc_transaction_save_commit_pre;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny ibox->save_commit_post = imapc_transaction_save_commit_post;
3c60433641ce2e86b9b04778c8f8652ef0d097e4Stef Walter ibox->save_rollback = imapc_transaction_save_rollback;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
8ccb0de226ccb9330f5a6865de487d6f0313902dJan Zeleny mbox->storage = (struct imapc_storage *)storage;
8ccb0de226ccb9330f5a6865de487d6f0313902dJan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny p_array_init(&mbox->untagged_callbacks, pool, 16);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny p_array_init(&mbox->resp_text_callbacks, pool, 16);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny imapc_mailbox_register_callbacks(mbox);
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny return &mbox->box;
f91e4aacb78d33791efcd744000597d5254dac4bSimo Sorce}
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zelenystatic void
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zelenyimapc_mailbox_open_callback(const struct imapc_command_reply *reply,
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny void *context)
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny{
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny struct imapc_open_context *ctx = context;
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny
20d0bc6d587f346238062df4da5edfde815e59b1Jan Zeleny if (reply->state == IMAPC_COMMAND_STATE_OK)
234958be042980242fff6da936af674da877c5efSimo Sorce ctx->ret = 0;
234958be042980242fff6da936af674da877c5efSimo Sorce else if (reply->state == IMAPC_COMMAND_STATE_NO) {
234958be042980242fff6da936af674da877c5efSimo Sorce imapc_copy_error_from_reply(ctx->mbox->storage,
234958be042980242fff6da936af674da877c5efSimo Sorce MAIL_ERROR_NOTFOUND, reply);
234958be042980242fff6da936af674da877c5efSimo Sorce ctx->ret = -1;
234958be042980242fff6da936af674da877c5efSimo Sorce } else {
234958be042980242fff6da936af674da877c5efSimo Sorce mail_storage_set_critical(ctx->mbox->box.storage,
234958be042980242fff6da936af674da877c5efSimo Sorce "imapc: Opening mailbox '%s' failed: %s",
234958be042980242fff6da936af674da877c5efSimo Sorce ctx->mbox->box.name, reply->text_full);
234958be042980242fff6da936af674da877c5efSimo Sorce ctx->ret = -1;
234958be042980242fff6da936af674da877c5efSimo Sorce }
234958be042980242fff6da936af674da877c5efSimo Sorce if (!ctx->mbox->new_msgs)
234958be042980242fff6da936af674da877c5efSimo Sorce imapc_client_stop(ctx->mbox->storage->client);
234958be042980242fff6da936af674da877c5efSimo Sorce}
234958be042980242fff6da936af674da877c5efSimo Sorce
234958be042980242fff6da936af674da877c5efSimo Sorcestatic int imapc_mailbox_open(struct mailbox *box)
234958be042980242fff6da936af674da877c5efSimo Sorce{
234958be042980242fff6da936af674da877c5efSimo Sorce struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
234958be042980242fff6da936af674da877c5efSimo Sorce struct imapc_open_context ctx;
234958be042980242fff6da936af674da877c5efSimo Sorce
234958be042980242fff6da936af674da877c5efSimo Sorce if (index_storage_mailbox_open(box, FALSE) < 0)
234958be042980242fff6da936af674da877c5efSimo Sorce return -1;
234958be042980242fff6da936af674da877c5efSimo Sorce
234958be042980242fff6da936af674da877c5efSimo Sorce if (box->deleting || (box->flags & MAILBOX_FLAG_SAVEONLY) != 0) {
234958be042980242fff6da936af674da877c5efSimo Sorce /* We don't actually want to SELECT the mailbox. */
234958be042980242fff6da936af674da877c5efSimo Sorce return 0;
234958be042980242fff6da936af674da877c5efSimo Sorce }
234958be042980242fff6da936af674da877c5efSimo Sorce
234958be042980242fff6da936af674da877c5efSimo Sorce mbox->opening = TRUE;
234958be042980242fff6da936af674da877c5efSimo Sorce ctx.mbox = mbox;
234958be042980242fff6da936af674da877c5efSimo Sorce ctx.ret = -1;
234958be042980242fff6da936af674da877c5efSimo Sorce mbox->client_box =
234958be042980242fff6da936af674da877c5efSimo Sorce imapc_client_mailbox_open(mbox->storage->client, box->name,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek imapc_mailbox_open_callback,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek &ctx, mbox);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek imapc_client_run(mbox->storage->client);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mbox->opening = FALSE;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (ctx.ret < 0) {
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mailbox_close(box);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return -1;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek }
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return 0;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek}
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekstatic void imapc_mailbox_close(struct mailbox *box)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek{
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (mbox->client_box != NULL)
144e7bad57748aaab395b9fb8ad136cdad864a00Lukas Slebodnik imapc_client_mailbox_close(&mbox->client_box);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (mbox->delayed_sync_view != NULL)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mail_index_view_close(&mbox->delayed_sync_view);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (mbox->delayed_sync_trans != NULL) {
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (mail_index_transaction_commit(&mbox->delayed_sync_trans) < 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mail_storage_set_index_error(&mbox->box);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek }
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (mbox->to_idle != NULL)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek timeout_remove(&mbox->to_idle);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return index_storage_mailbox_close(box);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek}
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekstatic int
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekimapc_mailbox_create(struct mailbox *box,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek const struct mailbox_update *update ATTR_UNUSED,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek bool directory)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek{
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek struct imapc_simple_context ctx;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek const char *name = box->name;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (directory) {
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek name = t_strdup_printf("%s%c", name,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mailbox_list_get_hierarchy_sep(box->list));
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek }
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek ctx.storage = mbox->storage;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek imapc_client_cmdf(mbox->storage->client, imapc_simple_callback, &ctx,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek "CREATE %s", name);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek imapc_client_run(mbox->storage->client);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return ctx.ret;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek}
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekstatic int imapc_mailbox_update(struct mailbox *box,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek const struct mailbox_update *update ATTR_UNUSED)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek{
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek "Not supported");
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return -1;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek}
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekstatic void imapc_untagged_status(const struct imapc_untagged_reply *reply,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek struct imapc_storage *storage)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek{
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek struct mailbox_status *status;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek const struct imap_arg *list;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek const char *name, *key, *value;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek uint32_t num;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek unsigned int i;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (!imap_arg_get_astring(&reply->args[0], &name) ||
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek !imap_arg_get_list(&reply->args[1], &list))
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (storage->cur_status_box == NULL ||
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek strcmp(storage->cur_status_box->box.name, name) != 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek status = storage->cur_status;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek for (i = 0; list[i].type != IMAP_ARG_EOL; i += 2) {
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (!imap_arg_get_atom(&list[i], &key) ||
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek !imap_arg_get_atom(&list[i+1], &value) ||
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek str_to_uint32(value, &num) < 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (strcasecmp(key, "MESSAGES") == 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek status->messages = num;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek else if (strcasecmp(key, "RECENT") == 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek status->recent = num;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek else if (strcasecmp(key, "UIDNEXT") == 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek status->uidnext = num;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek else if (strcasecmp(key, "UIDVALIDITY") == 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek status->uidvalidity = num;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek else if (strcasecmp(key, "UNSEEN") == 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek status->unseen = num;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek else if (strcasecmp(key, "HIGHESTMODSEQ") == 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek status->highest_modseq = num;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek }
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek}
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekstatic void imapc_mailbox_get_selected_status(struct imapc_mailbox *mbox,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek enum mailbox_status_items items,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek struct mailbox_status *status_r)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek{
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek index_storage_get_status(&mbox->box, items, status_r);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek}
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekstatic int imapc_mailbox_get_status(struct mailbox *box,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek enum mailbox_status_items items,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek struct mailbox_status *status_r)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek{
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek struct imapc_simple_context ctx;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek string_t *str;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek memset(status_r, 0, sizeof(*status_r));
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (box->opened) {
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek imapc_mailbox_get_selected_status(mbox, items, status_r);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return 0;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek }
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek /* mailbox isn't opened yet */
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if ((items & (STATUS_FIRST_UNSEEN_SEQ | STATUS_KEYWORDS)) != 0) {
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek /* getting these requires opening the mailbox */
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (mailbox_open(box) < 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return -1;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek imapc_mailbox_get_selected_status(mbox, items, status_r);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return 0;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek }
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek str = t_str_new(256);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if ((items & STATUS_MESSAGES) != 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek str_append(str, " MESSAGES");
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if ((items & STATUS_RECENT) != 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek str_append(str, " RECENT");
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if ((items & STATUS_UIDNEXT) != 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek str_append(str, " UIDNEXT");
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if ((items & STATUS_UIDVALIDITY) != 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek str_append(str, " UIDVALIDITY");
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if ((items & STATUS_UNSEEN) != 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek str_append(str, " UNSEEN");
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if ((items & STATUS_HIGHESTMODSEQ) != 0)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek str_append(str, " HIGHESTMODSEQ");
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if (str_len(str) == 0) {
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek /* nothing requested */
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return 0;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek }
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek ctx.storage = mbox->storage;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mbox->storage->cur_status_box = mbox;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mbox->storage->cur_status = status_r;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek imapc_client_cmdf(mbox->storage->client,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek imapc_simple_callback, &ctx,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek "STATUS %s (%1s)", box->name, str_c(str));
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek imapc_client_run(mbox->storage->client);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mbox->storage->cur_status_box = NULL;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mbox->storage->cur_status = NULL;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return ctx.ret;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek}
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekstatic int imapc_mailbox_get_metadata(struct mailbox *box,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek enum mailbox_metadata_items items,
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek struct mailbox_metadata *metadata_r)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek{
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek if ((items & MAILBOX_METADATA_GUID) != 0) {
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek /* a bit ugly way to do this, but better than nothing for now.
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek FIXME: if indexes are enabled, keep this there. */
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek mail_generate_guid_128_hash(box->name, metadata_r->guid);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek }
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek return index_mailbox_get_metadata(box, items, metadata_r);
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek}
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekstatic void imapc_notify_changes(struct mailbox *box ATTR_UNUSED)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek{
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek /* we're doing IDLE all the time anyway - nothing to do here */
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek}
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozekint imapc_create_temp_fd(struct mail_user *user, const char **path_r)
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek{
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek string_t *path;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek int fd;
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek
58dd26b1c5b60ee992dd5d1214bb168aebb42d54Jakub Hrozek path = t_str_new(128);
mail_user_set_get_temp_prefix(path, user->set);
fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
if (fd == -1) {
i_error("safe_mkstemp(%s) failed: %m", str_c(path));
return -1;
}
/* we just want the fd, unlink it */
if (unlink(str_c(path)) < 0) {
/* shouldn't happen.. */
i_error("unlink(%s) failed: %m", str_c(path));
(void)close(fd);
return -1;
}
*path_r = str_c(path);
return fd;
}
struct mail_storage imapc_storage = {
.name = IMAPC_STORAGE_NAME,
.class_flags = 0,
.v = {
NULL,
imapc_storage_alloc,
imapc_storage_create,
imapc_storage_destroy,
NULL,
imapc_storage_get_list_settings,
NULL,
imapc_mailbox_alloc,
NULL
}
};
struct mailbox imapc_mailbox = {
.v = {
index_storage_is_readonly,
index_storage_allow_new_keywords,
index_storage_mailbox_enable,
index_storage_mailbox_exists,
imapc_mailbox_open,
imapc_mailbox_close,
index_storage_mailbox_free,
imapc_mailbox_create,
imapc_mailbox_update,
index_storage_mailbox_delete,
index_storage_mailbox_rename,
imapc_mailbox_get_status,
imapc_mailbox_get_metadata,
NULL,
NULL,
imapc_mailbox_sync_init,
index_mailbox_sync_next,
imapc_mailbox_sync_deinit,
NULL,
imapc_notify_changes,
index_transaction_begin,
index_transaction_commit,
index_transaction_rollback,
NULL,
imapc_mail_alloc,
imapc_search_init,
imapc_search_deinit,
imapc_search_next_nonblock,
imapc_search_next_update_seq,
imapc_save_alloc,
imapc_save_begin,
imapc_save_continue,
imapc_save_finish,
imapc_save_cancel,
imapc_copy,
index_storage_is_inconsistent
}
};