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