pop3-migration-plugin.c revision 0e7d5ff38f28d8c85e197a031bbb66b322ff89e6
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2007-2012 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "lib.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "array.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "istream.h"
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen#include "istream-header-filter.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "sha1.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "message-size.h"
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen#include "mail-namespace.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-search-build.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-storage-private.h"
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen#include "pop3-migration-plugin.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen#define POP3_MIGRATION_CONTEXT(obj) \
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen MODULE_CONTEXT(obj, pop3_migration_storage_module)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define POP3_MIGRATION_MAIL_CONTEXT(obj) \
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen MODULE_CONTEXT(obj, pop3_migration_mail_module)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstruct pop3_uidl_map {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen uint32_t pop3_seq;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uint32_t imap_uid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* UIDL */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *pop3_uidl;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* LIST size */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uoff_t size;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* sha1(TOP 0) - set only when needed */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned char hdr_sha1[SHA1_RESULTLEN];
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int hdr_sha1_set:1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen};
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstruct imap_msg_map {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen uint32_t uid, pop3_seq;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen uoff_t psize;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const char *pop3_uidl;
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen /* sha1(header) - set only when needed */
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen unsigned char hdr_sha1[SHA1_RESULTLEN];
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen unsigned int hdr_sha1_set:1;
4d4d6d4745682790c20d759ba93dbea46b812c5dTimo Sirainen};
4d4d6d4745682790c20d759ba93dbea46b812c5dTimo Sirainen
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainenstruct pop3_migration_mail_storage {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen union mail_storage_module_context module_ctx;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *pop3_box_vname;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mailbox *pop3_box;
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen ARRAY_DEFINE(pop3_uidl_map, struct pop3_uidl_map);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int all_mailboxes:1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int pop3_all_hdr_sha1_set:1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen};
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstruct pop3_migration_mailbox {
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen union mailbox_module_context module_ctx;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ARRAY_DEFINE(imap_msg_map, struct imap_msg_map);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int first_unfound_idx;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int uidl_synced:1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int uidl_sync_failed:1;
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen unsigned int uidl_ordered:1;
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen};
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainenstatic const char *hdr_hash_skip_headers[] = {
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen "Content-Length",
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen "Status",
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen "X-IMAP",
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen "X-IMAPbase",
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen "X-Keywords",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "X-Message-Flag",
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen "X-Status",
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen "X-UID",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "X-UIDL"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen};
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenconst char *pop3_migration_plugin_version = DOVECOT_VERSION;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(pop3_migration_storage_module,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen &mail_storage_module_register);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(pop3_migration_mail_module,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen &mail_module_register);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstatic int imap_msg_map_uid_cmp(const struct imap_msg_map *map1,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const struct imap_msg_map *map2)
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (map1->uid < map2->uid)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (map1->uid > map2->uid)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
7fe37c2b0e4cd2a39896ab16e47eb418a59e3934Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int pop3_uidl_map_pop3_seq_cmp(const struct pop3_uidl_map *map1,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct pop3_uidl_map *map2)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (map1->pop3_seq < map2->pop3_seq)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen if (map1->pop3_seq > map2->pop3_seq)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 0;
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int pop3_uidl_map_hdr_cmp(const struct pop3_uidl_map *map1,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct pop3_uidl_map *map2)
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen{
0c22bef8f5b35c645de8affd8746307fc53bd222Timo Sirainen return memcmp(map1->hdr_sha1, map2->hdr_sha1, sizeof(map1->hdr_sha1));
0c22bef8f5b35c645de8affd8746307fc53bd222Timo Sirainen}
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainenstatic int imap_msg_map_hdr_cmp(const struct imap_msg_map *map1,
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen const struct imap_msg_map *map2)
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen{
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen return memcmp(map1->hdr_sha1, map2->hdr_sha1, sizeof(map1->hdr_sha1));
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen}
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainenstatic int get_hdr_sha1(struct mail *mail, unsigned char sha1[SHA1_RESULTLEN])
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen{
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen struct message_size hdr_size;
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen struct istream *input, *input2;
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen const unsigned char *data;
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen size_t size;
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen struct sha1_ctxt sha1_ctx;
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen if (mail_get_hdr_stream(mail, &hdr_size, &input) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_error("pop3_migration: Failed to get header for msg %u: %s",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail->seq, mailbox_get_last_error(mail->box, NULL));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen input2 = i_stream_create_limit(input, hdr_size.physical_size);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* hide headers that might change or be different in IMAP vs. POP3 */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen input = i_stream_create_header_filter(input2,
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR,
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen hdr_hash_skip_headers,
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen N_ELEMENTS(hdr_hash_skip_headers),
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen null_header_filter_callback, NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_stream_unref(&input2);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen sha1_init(&sha1_ctx);
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen while (i_stream_read_data(input, &data, &size, 0) > 0) {
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen sha1_loop(&sha1_ctx, data, size);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_stream_skip(input, size);
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen }
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen if (input->stream_errno != 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_error("pop3_migration: Failed to read header for msg %u: %m",
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen mail->seq);
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen i_stream_unref(&input);
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen return -1;
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen sha1_result(&sha1_ctx, sha1);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_stream_unref(&input);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return 0;
01230de017cd273de41143d88e9c18df1243ae8aTimo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int pop3_mailbox_open(struct mail_storage *storage)
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct pop3_migration_mail_storage *mstorage =
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen POP3_MIGRATION_CONTEXT(storage);
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen struct mail_namespace *ns;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mstorage->pop3_box != NULL)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ns = mail_namespace_find(storage->user->namespaces,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mstorage->pop3_box_vname);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (ns == NULL) {
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen i_error("pop3_migration: Namespace not found for mailbox %s",
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen mstorage->pop3_box_vname);
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen return -1;
7487ff578435377bbeefffdbfb78ca09ed1292dfTimo Sirainen }
7487ff578435377bbeefffdbfb78ca09ed1292dfTimo Sirainen mstorage->pop3_box = mailbox_alloc(ns->list, mstorage->pop3_box_vname,
7487ff578435377bbeefffdbfb78ca09ed1292dfTimo Sirainen MAILBOX_FLAG_READONLY |
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen MAILBOX_FLAG_POP3_SESSION);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mstorage->all_mailboxes =
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_user_plugin_getenv(storage->user,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "pop3_migration_all_mailboxes") != NULL;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int pop3_map_read(struct mail_storage *storage)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct pop3_migration_mail_storage *mstorage =
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen POP3_MIGRATION_CONTEXT(storage);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mailbox *pop3_box = mstorage->pop3_box;
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen struct mailbox_transaction_context *t;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_search_args *search_args;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_search_context *ctx;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail *mail;
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen struct pop3_uidl_map *map;
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen const char *uidl;
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen uoff_t size;
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen int ret = 0;
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen if (array_is_created(&mstorage->pop3_uidl_map)) {
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen /* already read these, just reset the imap_uids */
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen array_foreach_modifiable(&mstorage->pop3_uidl_map, map)
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen map->imap_uid = 0;
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen return 0;
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen }
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen i_array_init(&mstorage->pop3_uidl_map, 128);
e0740628f6ca05f4bc79a9d8a90b650f4d38d4d0Timo Sirainen
e0740628f6ca05f4bc79a9d8a90b650f4d38d4d0Timo Sirainen if (mailbox_sync(pop3_box, 0) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_error("pop3_migration: Couldn't sync mailbox %s: %s",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen pop3_box->vname, mailbox_get_last_error(pop3_box, NULL));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
c6335901c67a4c9365319190a111a2168f3b06f5Timo Sirainen }
c6335901c67a4c9365319190a111a2168f3b06f5Timo Sirainen
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen t = mailbox_transaction_begin(pop3_box, 0);
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen search_args = mail_search_build_init();
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen mail_search_build_add_all(search_args);
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen ctx = mailbox_search_init(t, search_args, NULL,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen MAIL_FETCH_VIRTUAL_SIZE, NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_search_args_unref(&search_args);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen while (mailbox_search_next(ctx, &mail)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mail_get_virtual_size(mail, &size) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_error("pop3_migration: Failed to get size for msg %u: %s",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail->seq,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mailbox_get_last_error(pop3_box, NULL));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = -1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen break;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mail_get_special(mail, MAIL_FETCH_UIDL_BACKEND, &uidl) < 0) {
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen i_error("pop3_migration: Failed to get UIDL for msg %u: %s",
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen mail->seq,
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen mailbox_get_last_error(pop3_box, NULL));
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen ret = -1;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen break;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen }
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (*uidl == '\0') {
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen i_warning("pop3_migration: UIDL for msg %u is empty",
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen mail->seq);
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen continue;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen map = array_append_space(&mstorage->pop3_uidl_map);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen map->pop3_seq = mail->seq;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen map->pop3_uidl = p_strdup(storage->pool, uidl);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen map->size = size;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (mailbox_search_deinit(&ctx) < 0)
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen ret = -1;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen (void)mailbox_transaction_commit(&t);
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen return ret;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int pop3_map_read_hdr_hashes(struct mail_storage *storage,
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen unsigned first_seq)
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen{
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen struct pop3_migration_mail_storage *mstorage =
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen POP3_MIGRATION_CONTEXT(storage);
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen struct mailbox_transaction_context *t;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen struct mail_search_args *search_args;
f5e1d3d6b34ec152aa1ff15c7bd3d3552e9227eaTimo Sirainen struct mail_search_context *ctx;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen struct mail *mail;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen struct pop3_uidl_map *map;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen int ret = 0;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (mstorage->pop3_all_hdr_sha1_set)
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mstorage->all_mailboxes) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* we may be matching against multiple mailboxes.
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen read all the hashes only once. */
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen first_seq = 1;
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen }
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen t = mailbox_transaction_begin(mstorage->pop3_box, 0);
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen search_args = mail_search_build_init();
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen mail_search_build_add_seqset(search_args, first_seq,
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen array_count(&mstorage->pop3_uidl_map)+1);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen ctx = mailbox_search_init(t, search_args, NULL,
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen MAIL_FETCH_STREAM_HEADER, NULL);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen mail_search_args_unref(&search_args);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen while (mailbox_search_next(ctx, &mail)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen map = array_idx_modifiable(&mstorage->pop3_uidl_map,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail->seq-1);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (get_hdr_sha1(mail, map->hdr_sha1) < 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen else
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen map->hdr_sha1_set = TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mailbox_search_deinit(&ctx) < 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = -1;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen (void)mailbox_transaction_commit(&t);
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen if (ret == 0 && first_seq == 1)
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen mstorage->pop3_all_hdr_sha1_set = TRUE;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen return ret;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen}
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen
047c00cd3f7f403672f81569413669238df8c15aTimo Sirainenstatic int imap_map_read(struct mailbox *box)
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct pop3_migration_mailbox *mbox = POP3_MIGRATION_CONTEXT(box);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mailbox_status status;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mailbox_transaction_context *t;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_search_args *search_args;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_search_context *ctx;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail *mail;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct imap_msg_map *map;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uoff_t psize;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen int ret = 0;
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen mailbox_get_open_status(box, STATUS_MESSAGES, &status);
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen i_assert(!array_is_created(&mbox->imap_msg_map));
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen p_array_init(&mbox->imap_msg_map, box->pool, status.messages);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen t = mailbox_transaction_begin(box, 0);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen search_args = mail_search_build_init();
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen mail_search_build_add_all(search_args);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen ctx = mailbox_search_init(t, search_args, NULL,
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen MAIL_FETCH_PHYSICAL_SIZE, NULL);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen mail_search_args_unref(&search_args);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen while (mailbox_search_next(ctx, &mail)) {
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen if (mail_get_physical_size(mail, &psize) < 0) {
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen i_error("pop3_migration: Failed to get psize for imap uid %u: %s",
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen mail->uid,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mailbox_get_last_error(box, NULL));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = -1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen break;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen map = array_append_space(&mbox->imap_msg_map);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen map->uid = mail->uid;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen map->psize = psize;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mailbox_search_deinit(&ctx) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = -1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (void)mailbox_transaction_commit(&t);
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen return ret;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic int imap_map_read_hdr_hashes(struct mailbox *box)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct pop3_migration_mailbox *mbox = POP3_MIGRATION_CONTEXT(box);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct mailbox_transaction_context *t;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct mail_search_args *search_args;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct mail_search_context *ctx;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct mail *mail;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct imap_msg_map *map;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int ret = 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen t = mailbox_transaction_begin(box, 0);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen search_args = mail_search_build_init();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_search_build_add_seqset(search_args, mbox->first_unfound_idx+1,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen array_count(&mbox->imap_msg_map)+1);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ctx = mailbox_search_init(t, search_args, NULL,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen MAIL_FETCH_STREAM_HEADER, NULL);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mail_search_args_unref(&search_args);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen while (mailbox_search_next(ctx, &mail)) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen map = array_idx_modifiable(&mbox->imap_msg_map, mail->seq-1);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (get_hdr_sha1(mail, map->hdr_sha1) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = -1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen else
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen map->hdr_sha1_set = TRUE;
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen }
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mailbox_search_deinit(&ctx) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = -1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (void)mailbox_transaction_commit(&t);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return ret;
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen}
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainenstatic bool pop3_uidl_assign_by_size(struct mailbox *box)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct pop3_migration_mailbox *mbox = POP3_MIGRATION_CONTEXT(box);
788f275469ad9ed530e440d6690d0e4381a323b2Timo Sirainen struct pop3_migration_mail_storage *mstorage =
788f275469ad9ed530e440d6690d0e4381a323b2Timo Sirainen POP3_MIGRATION_CONTEXT(box->storage);
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen struct pop3_uidl_map *pop3_map;
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen struct imap_msg_map *imap_map;
788f275469ad9ed530e440d6690d0e4381a323b2Timo Sirainen unsigned int i, pop3_count, imap_count, count;
788f275469ad9ed530e440d6690d0e4381a323b2Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pop3_map = array_get_modifiable(&mstorage->pop3_uidl_map, &pop3_count);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen imap_map = array_get_modifiable(&mbox->imap_msg_map, &imap_count);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen count = I_MIN(pop3_count, imap_count);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* see if we can match the messages using sizes */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (i = 0; i < count; i++) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (pop3_map[i].size != imap_map[i].psize)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen break;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if (i+1 < count && pop3_map[i].size == pop3_map[i+1].size) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* two messages with same size, don't trust them */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen break;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pop3_map[i].imap_uid = imap_map[i].uid;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen imap_map[i].pop3_uidl = pop3_map[i].pop3_uidl;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen imap_map[i].pop3_seq = pop3_map[i].pop3_seq;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mbox->first_unfound_idx = i;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return i == count;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
9240d99920783c56405dda74a1f6c7ff1ebed8e6Timo Sirainen
9240d99920783c56405dda74a1f6c7ff1ebed8e6Timo Sirainenstatic int pop3_uidl_assign_by_hdr_hash(struct mailbox *box)
9240d99920783c56405dda74a1f6c7ff1ebed8e6Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct pop3_migration_mail_storage *mstorage =
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen POP3_MIGRATION_CONTEXT(box->storage);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct pop3_migration_mailbox *mbox = POP3_MIGRATION_CONTEXT(box);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct pop3_uidl_map *pop3_map;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct imap_msg_map *imap_map;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int pop3_idx, imap_idx, pop3_count, imap_count;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int first_seq, missing_uids_count;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen int ret;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen first_seq = mbox->first_unfound_idx+1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (pop3_map_read_hdr_hashes(box->storage, first_seq) < 0 ||
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen imap_map_read_hdr_hashes(box) < 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen array_sort(&mstorage->pop3_uidl_map, pop3_uidl_map_hdr_cmp);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen array_sort(&mbox->imap_msg_map, imap_msg_map_hdr_cmp);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen pop3_map = array_get_modifiable(&mstorage->pop3_uidl_map, &pop3_count);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen imap_map = array_get_modifiable(&mbox->imap_msg_map, &imap_count);
9240d99920783c56405dda74a1f6c7ff1ebed8e6Timo Sirainen
9240d99920783c56405dda74a1f6c7ff1ebed8e6Timo Sirainen pop3_idx = imap_idx = 0;
9240d99920783c56405dda74a1f6c7ff1ebed8e6Timo Sirainen while (pop3_idx < pop3_count && imap_idx < imap_count) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!pop3_map[pop3_idx].hdr_sha1_set ||
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen pop3_map[pop3_idx].imap_uid != 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pop3_idx++;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen continue;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen if (!imap_map[imap_idx].hdr_sha1_set ||
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen imap_map[imap_idx].pop3_uidl != NULL) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen imap_idx++;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen continue;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen ret = memcmp(pop3_map[pop3_idx].hdr_sha1,
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen imap_map[imap_idx].hdr_sha1,
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen sizeof(pop3_map[pop3_idx].hdr_sha1));
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen if (ret < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pop3_idx++;
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen else if (ret > 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen imap_idx++;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen else {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pop3_map[pop3_idx].imap_uid = imap_map[imap_idx].uid;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen imap_map[imap_idx].pop3_uidl =
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pop3_map[pop3_idx].pop3_uidl;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen imap_map[imap_idx].pop3_seq =
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pop3_map[pop3_idx].pop3_seq;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen missing_uids_count = 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (pop3_idx = 0; pop3_idx < pop3_count; pop3_idx++) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (pop3_map[pop3_idx].imap_uid == 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen missing_uids_count++;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (missing_uids_count > 0 && !mstorage->all_mailboxes) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_warning("pop3_migration: %u POP3 messages have no "
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "matching IMAP messages", missing_uids_count);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen array_sort(&mstorage->pop3_uidl_map, pop3_uidl_map_pop3_seq_cmp);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen array_sort(&mbox->imap_msg_map, imap_msg_map_uid_cmp);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic int pop3_migration_uidl_sync(struct mailbox *box)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct pop3_migration_mailbox *mbox = POP3_MIGRATION_CONTEXT(box);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct pop3_migration_mail_storage *mstorage =
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen POP3_MIGRATION_CONTEXT(box->storage);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const struct pop3_uidl_map *pop3_map;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen unsigned int i, count;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen uint32_t prev_uid;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mbox->uidl_synced)
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen return 0;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if (pop3_mailbox_open(box->storage) < 0)
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen return -1;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen /* the POP3 server isn't connected to yet. handle all IMAP traffic
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen first before connecting, so POP3 server won't disconnect us due to
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen idling. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (imap_map_read(box) < 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (pop3_map_read(box->storage) < 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!pop3_uidl_assign_by_size(box)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* everything wasn't assigned, figure out the rest with
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen header hashes */
b2d562f9c7fd13f9a16e9b3bcee904630b80b1feTimo Sirainen if (pop3_uidl_assign_by_hdr_hash(box) < 0)
b2d562f9c7fd13f9a16e9b3bcee904630b80b1feTimo Sirainen return -1;
b2d562f9c7fd13f9a16e9b3bcee904630b80b1feTimo Sirainen }
b2d562f9c7fd13f9a16e9b3bcee904630b80b1feTimo Sirainen
b2d562f9c7fd13f9a16e9b3bcee904630b80b1feTimo Sirainen /* see if the POP3 UIDL order is the same as IMAP UID order */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mbox->uidl_ordered = TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pop3_map = array_get(&mstorage->pop3_uidl_map, &count);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen prev_uid = 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (i = 0; i < count; i++) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (pop3_map[i].imap_uid == 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen continue;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (prev_uid > pop3_map[i].imap_uid) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mbox->uidl_ordered = FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen break;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen prev_uid = pop3_map[i].imap_uid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen mbox->uidl_synced = TRUE;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen return 0;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen}
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainenstatic int
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainenpop3_migration_get_special(struct mail *_mail, enum mail_fetch_field field,
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen const char **value_r)
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen{
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen union mail_module_context *mmail = POP3_MIGRATION_MAIL_CONTEXT(mail);
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen struct pop3_migration_mailbox *mbox = POP3_MIGRATION_CONTEXT(_mail->box);
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen struct imap_msg_map map_key, *map;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen if (field == MAIL_FETCH_UIDL_BACKEND ||
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen field == MAIL_FETCH_POP3_ORDER) {
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen if (mbox->uidl_sync_failed ||
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen pop3_migration_uidl_sync(_mail->box) < 0) {
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen mbox->uidl_sync_failed = TRUE;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen mail_storage_set_error(_mail->box->storage,
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen MAIL_ERROR_TEMP,
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen "POP3 UIDLs couldn't be synced");
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen return -1;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen }
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen memset(&map_key, 0, sizeof(map_key));
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen map_key.uid = _mail->uid;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen map = array_bsearch(&mbox->imap_msg_map, &map_key,
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen imap_msg_map_uid_cmp);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen if (map != NULL && map->pop3_uidl != NULL) {
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen if (field == MAIL_FETCH_UIDL_BACKEND)
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen *value_r = map->pop3_uidl;
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen else
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen *value_r = t_strdup_printf("%u", map->pop3_seq);
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen return 0;
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen }
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen /* not found from POP3 server, fallback to default */
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen }
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen return mmail->super.get_special(_mail, field, value_r);
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen}
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainenstatic void pop3_migration_mail_allocated(struct mail *_mail)
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen{
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen struct pop3_migration_mail_storage *mstorage =
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen POP3_MIGRATION_CONTEXT(_mail->box->storage);
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen struct mail_vfuncs *v = mail->vlast;
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen union mail_module_context *mmail;
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen struct mail_namespace *ns;
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen if (mstorage == NULL ||
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen (!mstorage->all_mailboxes && !_mail->box->inbox_user)) {
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen /* assigns UIDLs only for INBOX */
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen return;
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen }
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen ns = mail_namespace_find(_mail->box->storage->user->namespaces,
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen mstorage->pop3_box_vname);
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen if (ns == mailbox_get_namespace(_mail->box)) {
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen /* we're accessing the pop3-migration namespace itself */
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen return;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen mmail = p_new(mail->pool, union mail_module_context, 1);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen mmail->super = *v;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail->vlast = &mmail->super;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen v->get_special = pop3_migration_get_special;
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen MODULE_CONTEXT_SET_SELF(mail, pop3_migration_mail_module, mmail);
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen}
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainenstatic void pop3_migration_mailbox_allocated(struct mailbox *box)
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen{
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen struct mailbox_vfuncs *v = box->vlast;
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen struct pop3_migration_mailbox *mbox;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen mbox = p_new(box->pool, struct pop3_migration_mailbox, 1);
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen mbox->module_ctx.super = *v;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen box->vlast = &mbox->module_ctx.super;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen MODULE_CONTEXT_SET(box, pop3_migration_storage_module, mbox);
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen}
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainenstatic void pop3_migration_mail_storage_destroy(struct mail_storage *storage)
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen{
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen struct pop3_migration_mail_storage *mstorage =
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen POP3_MIGRATION_CONTEXT(storage);
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen if (mstorage->pop3_box != NULL)
c668292359474a4aa8c608b30a858337fa3fc813Timo Sirainen mailbox_free(&mstorage->pop3_box);
c668292359474a4aa8c608b30a858337fa3fc813Timo Sirainen if (array_is_created(&mstorage->pop3_uidl_map))
c668292359474a4aa8c608b30a858337fa3fc813Timo Sirainen array_free(&mstorage->pop3_uidl_map);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen if (mstorage->module_ctx.super.destroy != NULL)
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen mstorage->module_ctx.super.destroy(storage);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void pop3_migration_mail_storage_created(struct mail_storage *storage)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct pop3_migration_mail_storage *mstorage;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct mail_storage_vfuncs *v = storage->vlast;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const char *pop3_box_vname;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen pop3_box_vname = mail_user_plugin_getenv(storage->user,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen "pop3_migration_mailbox");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (pop3_box_vname == NULL)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mstorage = p_new(storage->pool, struct pop3_migration_mail_storage, 1);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mstorage->module_ctx.super = *v;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen storage->vlast = &mstorage->module_ctx.super;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen v->destroy = pop3_migration_mail_storage_destroy;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mstorage->pop3_box_vname = p_strdup(storage->pool, pop3_box_vname);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen MODULE_CONTEXT_SET(storage, pop3_migration_storage_module, mstorage);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen}
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstatic struct mail_storage_hooks pop3_migration_mail_storage_hooks = {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen .mail_allocated = pop3_migration_mail_allocated,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen .mailbox_allocated = pop3_migration_mailbox_allocated,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen .mail_storage_created = pop3_migration_mail_storage_created
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen};
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenvoid pop3_migration_plugin_init(struct module *module)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mail_storage_hooks_add(module, &pop3_migration_mail_storage_hooks);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen}
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenvoid pop3_migration_plugin_deinit(void)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mail_storage_hooks_remove(&pop3_migration_mail_storage_hooks);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen}
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen