pop3c-storage.c revision c69a177207ed18d0f0210347430a60957136bd6c
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2011-2017 Dovecot authors, see the included COPYING file */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#include "lib.h"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#include "ioloop.h"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#include "str.h"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#include "mail-copy.h"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#include "mail-user.h"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#include "mailbox-list-private.h"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#include "index-mail.h"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#include "pop3c-client.h"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#include "pop3c-sync.h"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#include "pop3c-storage.h"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#define DNS_CLIENT_SOCKET_NAME "dns-client"
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
0db42260be85e797aa9909a29b20296996f52e75Timo Sirainenextern struct mail_storage pop3c_storage;
0db42260be85e797aa9909a29b20296996f52e75Timo Sirainenextern struct mailbox pop3c_mailbox;
0db42260be85e797aa9909a29b20296996f52e75Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic struct mail_storage *pop3c_storage_alloc(void)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct pop3c_storage *storage;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pool_t pool;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pool = pool_alloconly_create("pop3c storage", 512+256);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen storage = p_new(pool, struct pop3c_storage, 1);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen storage->storage = pop3c_storage;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen storage->storage.pool = pool;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return &storage->storage;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic int
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenpop3c_storage_create(struct mail_storage *_storage,
46e917c9fa05cbe7bddf805d3a9838b61e3960e1Timo Sirainen struct mail_namespace *ns,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen const char **error_r)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
95d62f8d6d281cc488dc4f488d4388701e559012Josef 'Jeff' Sipek struct pop3c_storage *storage = POP3C_STORAGE(_storage);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
46e917c9fa05cbe7bddf805d3a9838b61e3960e1Timo Sirainen storage->set = mail_namespace_get_driver_settings(ns, _storage);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (storage->set->pop3c_host[0] == '\0') {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen *error_r = "missing pop3c_host";
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return -1;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen }
b49aa341d28c0eec1229e30baa2f89d5bae52ff8Phil Carmody if (storage->set->pop3c_password[0] == '\0') {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen *error_r = "missing pop3c_password";
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return -1;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen }
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return 0;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic struct pop3c_client *
16cb5d65265dd0b216542803fd80c4b999ae118eTimo Sirainenpop3c_client_create_from_set(struct mail_storage *storage,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen const struct pop3c_settings *set)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct pop3c_client_settings client_set;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen string_t *str;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&client_set);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.host = set->pop3c_host;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.port = set->pop3c_port;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.username = set->pop3c_user;
0ca3b9cb0f2a322a25ce7f229dc3d3a0b46be17bTimo Sirainen client_set.master_user = set->pop3c_master_user;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.password = set->pop3c_password;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.dns_client_socket_path =
7a88e726e7300fb0273cb4e55b43c27fbd90bdbdTimo Sirainen storage->user->set->base_dir[0] == '\0' ? "" :
16cb5d65265dd0b216542803fd80c4b999ae118eTimo Sirainen t_strconcat(storage->user->set->base_dir, "/",
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen DNS_CLIENT_SOCKET_NAME, NULL);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen str = t_str_new(128);
16cb5d65265dd0b216542803fd80c4b999ae118eTimo Sirainen mail_user_set_get_temp_prefix(str, storage->user->set);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.temp_path_prefix = str_c(str);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
16cb5d65265dd0b216542803fd80c4b999ae118eTimo Sirainen client_set.debug = storage->user->mail_debug;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.rawlog_dir =
16cb5d65265dd0b216542803fd80c4b999ae118eTimo Sirainen mail_user_home_expand(storage->user, set->pop3c_rawlog_dir);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
16cb5d65265dd0b216542803fd80c4b999ae118eTimo Sirainen client_set.ssl_ca_dir = storage->set->ssl_client_ca_dir;
56d1345c43bbd28c36b7faa85e4163bd9e874290Timo Sirainen client_set.ssl_ca_file = storage->set->ssl_client_ca_file;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.ssl_verify = set->pop3c_ssl_verify;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (strcmp(set->pop3c_ssl, "pop3s") == 0)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.ssl_mode = POP3C_CLIENT_SSL_MODE_IMMEDIATE;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen else if (strcmp(set->pop3c_ssl, "starttls") == 0)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.ssl_mode = POP3C_CLIENT_SSL_MODE_STARTTLS;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen else
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_set.ssl_mode = POP3C_CLIENT_SSL_MODE_NONE;
16cb5d65265dd0b216542803fd80c4b999ae118eTimo Sirainen client_set.ssl_crypto_device = storage->set->ssl_crypto_device;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return pop3c_client_init(&client_set);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic void
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenpop3c_storage_get_list_settings(const struct mail_namespace *ns,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct mailbox_list_settings *set)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen set->layout = MAILBOX_LIST_NAME_FS;
56aa97d74071f3a2987140c2ff1cfd5a59cb35aaTimo Sirainen if (set->root_dir != NULL && *set->root_dir != '\0' &&
56aa97d74071f3a2987140c2ff1cfd5a59cb35aaTimo Sirainen set->index_dir == NULL) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* we don't really care about root_dir, but we
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen just need to get index_dir autocreated.
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen it happens when index_dir differs from root_dir. */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen set->index_dir = set->root_dir;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen set->root_dir = p_strconcat(ns->user->pool,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen set->root_dir, "/.", NULL);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen }
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic struct mailbox *
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenpop3c_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen const char *vname, enum mailbox_flags flags)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct pop3c_mailbox *mbox;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pool_t pool;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pool = pool_alloconly_create("pop3c mailbox", 1024*3);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mbox = p_new(pool, struct pop3c_mailbox, 1);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mbox->box = pop3c_mailbox;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mbox->box.pool = pool;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mbox->box.storage = storage;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mbox->box.list = list;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mbox->box.mail_vfuncs = &pop3c_mail_vfuncs;
95d62f8d6d281cc488dc4f488d4388701e559012Josef 'Jeff' Sipek mbox->storage = POP3C_STORAGE(storage);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen index_storage_mailbox_alloc(&mbox->box, vname, flags, MAIL_INDEX_PREFIX);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return &mbox->box;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic int
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenpop3c_mailbox_exists(struct mailbox *box, bool auto_boxes ATTR_UNUSED,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen enum mailbox_existence *existence_r)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (box->inbox_any)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen *existence_r = MAILBOX_EXISTENCE_SELECT;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen else
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen *existence_r = MAILBOX_EXISTENCE_NONE;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return 0;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic void pop3c_login_callback(enum pop3c_command_state state,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen const char *reply, void *context)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct pop3c_mailbox *mbox = context;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen switch (state) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen case POP3C_COMMAND_STATE_OK:
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mbox->logged_in = TRUE;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen break;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen case POP3C_COMMAND_STATE_ERR:
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (strncmp(reply, "[IN-USE] ", 9) == 0) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mail_storage_set_error(mbox->box.storage,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen MAIL_ERROR_INUSE, reply + 9);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen } else {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* authentication failure probably */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mail_storage_set_error(mbox->box.storage,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen MAIL_ERROR_PARAMS, reply);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen }
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen break;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen case POP3C_COMMAND_STATE_DISCONNECTED:
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mail_storage_set_critical(mbox->box.storage,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen "pop3c: Disconnected from remote server");
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen break;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen }
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic int pop3c_mailbox_open(struct mailbox *box)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
95d62f8d6d281cc488dc4f488d4388701e559012Josef 'Jeff' Sipek struct pop3c_mailbox *mbox = POP3C_MAILBOX(box);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
9a1f68e5ab08eabd352d533315cba1c69006e2c1Timo Sirainen if (strcmp(box->name, "INBOX") != 0) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
bdb026e2dc8a7c77585ed5ba489f0056df8074d4Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname));
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return -1;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen }
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (index_storage_mailbox_open(box, FALSE) < 0)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return -1;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
16cb5d65265dd0b216542803fd80c4b999ae118eTimo Sirainen mbox->client = pop3c_client_create_from_set(box->storage,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mbox->storage->set);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_client_login(mbox->client, pop3c_login_callback, mbox);
60d1fdf2c17fd0c7020234590dbd73da81c3ce8fTimo Sirainen pop3c_client_wait_one(mbox->client);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return mbox->logged_in ? 0 : -1;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic void pop3c_mailbox_close(struct mailbox *box)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
95d62f8d6d281cc488dc4f488d4388701e559012Josef 'Jeff' Sipek struct pop3c_mailbox *mbox = POP3C_MAILBOX(box);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
c69a177207ed18d0f0210347430a60957136bd6cJosef 'Jeff' Sipek pool_unref(&mbox->uidl_pool);
5cdb246858f37469fe61351dbc147dabbdde342cTimo Sirainen i_free_and_null(mbox->msg_uids);
5cdb246858f37469fe61351dbc147dabbdde342cTimo Sirainen i_free_and_null(mbox->msg_sizes);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_client_deinit(&mbox->client);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_mailbox_close(box);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic int
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenpop3c_mailbox_create(struct mailbox *box,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen const struct mailbox_update *update ATTR_UNUSED,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen bool directory ATTR_UNUSED)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen "POP3 mailbox creation isn't supported");
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return -1;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic int
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenpop3c_mailbox_update(struct mailbox *box,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen const struct mailbox_update *update ATTR_UNUSED)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
5d4a0dac041964a04405bc6b94de51315ca917afTimo Sirainen if (!guid_128_is_empty(update->mailbox_guid) ||
5d4a0dac041964a04405bc6b94de51315ca917afTimo Sirainen update->uid_validity != 0 || update->min_next_uid != 0 ||
5d4a0dac041964a04405bc6b94de51315ca917afTimo Sirainen update->min_first_recent_uid != 0) {
5d4a0dac041964a04405bc6b94de51315ca917afTimo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
5d4a0dac041964a04405bc6b94de51315ca917afTimo Sirainen "POP3 mailbox update isn't supported");
5d4a0dac041964a04405bc6b94de51315ca917afTimo Sirainen }
5d4a0dac041964a04405bc6b94de51315ca917afTimo Sirainen return index_storage_mailbox_update(box, update);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainenstatic int pop3c_mailbox_get_status(struct mailbox *box,
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen enum mailbox_status_items items,
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen struct mailbox_status *status_r)
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen{
95d62f8d6d281cc488dc4f488d4388701e559012Josef 'Jeff' Sipek struct pop3c_mailbox *mbox = POP3C_MAILBOX(box);
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen if (index_storage_get_status(box, items, status_r) < 0)
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen return -1;
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen if ((pop3c_client_get_capabilities(mbox->client) &
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen POP3C_CAPABILITY_UIDL) == 0)
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen status_r->have_guids = FALSE;
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen return 0;
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen}
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainenstatic int pop3c_mailbox_get_metadata(struct mailbox *box,
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen enum mailbox_metadata_items items,
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen struct mailbox_metadata *metadata_r)
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen{
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen if ((items & MAILBOX_METADATA_GUID) != 0) {
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen /* a bit ugly way to do this, but better than nothing for now.
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen FIXME: if indexes are enabled, keep this there. */
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen mail_generate_guid_128_hash(box->name, metadata_r->guid);
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen items &= ~MAILBOX_METADATA_GUID;
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen }
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen if (items != 0) {
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen if (index_mailbox_get_metadata(box, items, metadata_r) < 0)
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen return -1;
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen }
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen return 0;
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen}
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic void pop3c_notify_changes(struct mailbox *box ATTR_UNUSED)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainenstatic struct mail_save_context *
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainenpop3c_save_alloc(struct mailbox_transaction_context *t)
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen{
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen struct mail_save_context *ctx;
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen ctx = i_new(struct mail_save_context, 1);
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen ctx->transaction = t;
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen return ctx;
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen}
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainenstatic int
1ee74d70bb758637e560d556c7240563967d22c8Timo Sirainenpop3c_save_begin(struct mail_save_context *ctx,
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen struct istream *input ATTR_UNUSED)
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen{
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen mail_storage_set_error(ctx->transaction->box->storage,
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen MAIL_ERROR_NOTPOSSIBLE, "POP3 doesn't support saving mails");
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen return -1;
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen}
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainenstatic int pop3c_save_continue(struct mail_save_context *ctx ATTR_UNUSED)
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen{
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen return -1;
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen}
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen
1ee74d70bb758637e560d556c7240563967d22c8Timo Sirainenstatic int pop3c_save_finish(struct mail_save_context *ctx)
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen{
1ee74d70bb758637e560d556c7240563967d22c8Timo Sirainen index_save_context_free(ctx);
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen return -1;
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen}
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainenstatic void
1ee74d70bb758637e560d556c7240563967d22c8Timo Sirainenpop3c_save_cancel(struct mail_save_context *ctx)
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen{
1ee74d70bb758637e560d556c7240563967d22c8Timo Sirainen index_save_context_free(ctx);
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen}
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic bool pop3c_storage_is_inconsistent(struct mailbox *box)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen{
95d62f8d6d281cc488dc4f488d4388701e559012Josef 'Jeff' Sipek struct pop3c_mailbox *mbox = POP3C_MAILBOX(box);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return index_storage_is_inconsistent(box) ||
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen !pop3c_client_is_connected(mbox->client);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen}
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstruct mail_storage pop3c_storage = {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen .name = POP3C_STORAGE_NAME,
e130bb802c8bfb6c6cc44e5c8bc098b4fa5af789Timo Sirainen .class_flags = MAIL_STORAGE_CLASS_FLAG_NO_ROOT |
e130bb802c8bfb6c6cc44e5c8bc098b4fa5af789Timo Sirainen MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_GUIDS,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen .v = {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_get_setting_parser_info,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_storage_alloc,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_storage_create,
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen index_storage_destroy,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen NULL,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_storage_get_list_settings,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen NULL,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_mailbox_alloc,
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen NULL,
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen NULL,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen }
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen};
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstruct mailbox pop3c_mailbox = {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen .v = {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_is_readonly,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_mailbox_enable,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_mailbox_exists,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_mailbox_open,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_mailbox_close,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_mailbox_free,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_mailbox_create,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_mailbox_update,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_mailbox_delete,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_mailbox_rename,
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen pop3c_mailbox_get_status,
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen pop3c_mailbox_get_metadata,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_set_subscribed,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_set,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_get,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_init,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_next,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_deinit,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_list_index_has_changed,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_list_index_update_sync,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_storage_sync_init,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_mailbox_sync_next,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_mailbox_sync_deinit,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen NULL,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_notify_changes,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_transaction_begin,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_transaction_commit,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_transaction_rollback,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen NULL,
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen pop3c_mail_alloc,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_search_init,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_search_deinit,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_search_next_nonblock,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen index_storage_search_next_update_seq,
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen pop3c_save_alloc,
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen pop3c_save_begin,
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen pop3c_save_continue,
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen pop3c_save_finish,
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen pop3c_save_cancel,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mail_storage_copy,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen NULL,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen NULL,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen NULL,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen pop3c_storage_is_inconsistent
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen }
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen};