43
43
union mail_storage_module_context module_ctx;
45
45
const char *pop3_box_vname;
46
struct mailbox *pop3_box;
47
ARRAY_DEFINE(pop3_uidl_map, struct pop3_uidl_map);
46
ARRAY(struct pop3_uidl_map) pop3_uidl_map;
49
48
unsigned int all_mailboxes:1;
50
49
unsigned int pop3_all_hdr_sha1_set:1;
53
52
struct pop3_migration_mailbox {
54
53
union mailbox_module_context module_ctx;
56
ARRAY_DEFINE(imap_msg_map, struct imap_msg_map);
55
ARRAY(struct imap_msg_map) imap_msg_map;
57
56
unsigned int first_unfound_idx;
59
58
unsigned int uidl_synced:1;
75
const char *pop3_migration_plugin_version = DOVECOT_VERSION;
74
const char *pop3_migration_plugin_version = DOVECOT_ABI_VERSION;
77
76
static MODULE_CONTEXT_DEFINE_INIT(pop3_migration_storage_module,
78
77
&mail_storage_module_register);
130
129
HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR,
131
130
hdr_hash_skip_headers,
132
131
N_ELEMENTS(hdr_hash_skip_headers),
133
null_header_filter_callback, NULL);
132
*null_header_filter_callback, (void *)NULL);
134
133
i_stream_unref(&input2);
136
135
sha1_init(&sha1_ctx);
152
static int pop3_mailbox_open(struct mail_storage *storage)
151
static struct mailbox *pop3_mailbox_alloc(struct mail_storage *storage)
154
153
struct pop3_migration_mail_storage *mstorage =
155
154
POP3_MIGRATION_CONTEXT(storage);
156
155
struct mail_namespace *ns;
158
if (mstorage->pop3_box != NULL)
161
157
ns = mail_namespace_find(storage->user->namespaces,
162
158
mstorage->pop3_box_vname);
164
i_error("pop3_migration: Namespace not found for mailbox %s",
165
mstorage->pop3_box_vname);
168
mstorage->pop3_box = mailbox_alloc(ns->list, mstorage->pop3_box_vname,
169
MAILBOX_FLAG_READONLY |
170
MAILBOX_FLAG_POP3_SESSION);
171
mstorage->all_mailboxes =
172
mail_user_plugin_getenv(storage->user,
173
"pop3_migration_all_mailboxes") != NULL;
159
i_assert(ns != NULL);
160
return mailbox_alloc(ns->list, mstorage->pop3_box_vname,
161
MAILBOX_FLAG_READONLY | MAILBOX_FLAG_POP3_SESSION);
177
static int pop3_map_read(struct mail_storage *storage)
164
static int pop3_map_read(struct mail_storage *storage, struct mailbox *pop3_box)
179
166
struct pop3_migration_mail_storage *mstorage =
180
167
POP3_MIGRATION_CONTEXT(storage);
181
struct mailbox *pop3_box = mstorage->pop3_box;
182
168
struct mailbox_transaction_context *t;
183
169
struct mail_search_args *search_args;
184
170
struct mail_search_context *ctx;
245
static int pop3_map_read_hdr_hashes(struct mail_storage *storage,
232
pop3_map_read_hdr_hashes(struct mail_storage *storage, struct mailbox *pop3_box,
248
235
struct pop3_migration_mail_storage *mstorage =
249
236
POP3_MIGRATION_CONTEXT(storage);
265
t = mailbox_transaction_begin(mstorage->pop3_box, 0);
252
t = mailbox_transaction_begin(pop3_box, 0);
266
253
search_args = mail_search_build_init();
267
254
mail_search_build_add_seqset(search_args, first_seq,
268
255
array_count(&mstorage->pop3_uidl_map)+1);
395
382
return i == count;
398
static int pop3_uidl_assign_by_hdr_hash(struct mailbox *box)
386
pop3_uidl_assign_by_hdr_hash(struct mailbox *box, struct mailbox *pop3_box)
400
388
struct pop3_migration_mail_storage *mstorage =
401
389
POP3_MIGRATION_CONTEXT(box->storage);
409
397
first_seq = mbox->first_unfound_idx+1;
410
if (pop3_map_read_hdr_hashes(box->storage, first_seq) < 0 ||
398
if (pop3_map_read_hdr_hashes(box->storage, pop3_box, first_seq) < 0 ||
411
399
imap_map_read_hdr_hashes(box) < 0)
463
451
struct pop3_migration_mailbox *mbox = POP3_MIGRATION_CONTEXT(box);
464
452
struct pop3_migration_mail_storage *mstorage =
465
453
POP3_MIGRATION_CONTEXT(box->storage);
454
struct mailbox *pop3_box;
466
455
const struct pop3_uidl_map *pop3_map;
467
456
unsigned int i, count;
468
457
uint32_t prev_uid;
470
459
if (mbox->uidl_synced)
473
if (pop3_mailbox_open(box->storage) < 0)
476
if (pop3_map_read(box->storage) < 0 || imap_map_read(box) < 0)
462
pop3_box = pop3_mailbox_alloc(box->storage);
463
/* the POP3 server isn't connected to yet. handle all IMAP traffic
464
first before connecting, so POP3 server won't disconnect us due to
466
if (imap_map_read(box) < 0 ||
467
pop3_map_read(box->storage, pop3_box) < 0) {
468
mailbox_free(&pop3_box);
479
472
if (!pop3_uidl_assign_by_size(box)) {
480
473
/* everything wasn't assigned, figure out the rest with
482
if (pop3_uidl_assign_by_hdr_hash(box) < 0)
475
if (pop3_uidl_assign_by_hdr_hash(box, pop3_box) < 0) {
476
mailbox_free(&pop3_box);
486
481
/* see if the POP3 UIDL order is the same as IMAP UID order */
585
581
struct pop3_migration_mail_storage *mstorage =
586
582
POP3_MIGRATION_CONTEXT(storage);
588
if (mstorage->pop3_box != NULL)
589
mailbox_free(&mstorage->pop3_box);
590
584
if (array_is_created(&mstorage->pop3_uidl_map))
591
585
array_free(&mstorage->pop3_uidl_map);
593
if (mstorage->module_ctx.super.destroy != NULL)
594
mstorage->module_ctx.super.destroy(storage);
587
mstorage->module_ctx.super.destroy(storage);
597
590
static void pop3_migration_mail_storage_created(struct mail_storage *storage)
611
604
v->destroy = pop3_migration_mail_storage_destroy;
613
606
mstorage->pop3_box_vname = p_strdup(storage->pool, pop3_box_vname);
607
mstorage->all_mailboxes =
608
mail_user_plugin_getenv(storage->user,
609
"pop3_migration_all_mailboxes") != NULL;
615
611
MODULE_CONTEXT_SET(storage, pop3_migration_storage_module, mstorage);