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