470
mailbox_move_all_mails(struct mailbox_list *list,
471
const char *src_name, const char *dest_name)
473
struct mail_storage *storage = list->ns->storage;
474
struct mailbox *src_box, *dest_box;
475
struct mail_search_args *search_args;
476
struct mailbox_transaction_context *src_trans, *dest_trans;
477
struct mail_search_context *search_ctx;
478
struct mail_save_context *save_ctx;
480
struct mail_keywords *keywords;
481
const char *const *keywords_list;
483
enum mail_error error;
486
dest_box = mailbox_open(&storage, dest_name, NULL, 0);
487
if (dest_box == NULL) {
488
errstr = mail_storage_get_last_error(storage, &error);
489
i_error("lazy_expunge: Couldn't open DELETE dest mailbox "
490
"%s: %s", dest_name, errstr);
494
src_box = mailbox_open(&storage, src_name, NULL,
495
MAILBOX_OPEN_KEEP_LOCKED);
496
if (src_box == NULL) {
497
errstr = mail_storage_get_last_error(storage, &error);
498
if (error == MAIL_ERROR_NOTFOUND)
500
i_error("lazy_expunge: Couldn't open DELETE source mailbox "
501
"%s: %s", src_name, errstr);
505
src_trans = mailbox_transaction_begin(src_box, 0);
506
dest_trans = mailbox_transaction_begin(dest_box,
507
MAILBOX_TRANSACTION_FLAG_EXTERNAL);
509
search_args = mail_search_build_init();
510
mail_search_build_add_all(search_args);
511
search_ctx = mailbox_search_init(src_trans, search_args, NULL);
512
mail_search_args_unref(&search_args);
514
mail = mail_alloc(src_trans, 0, NULL);
515
while ((ret = mailbox_search_next(search_ctx, mail)) > 0) {
516
keywords_list = mail_get_keywords(mail);
517
keywords = str_array_length(keywords_list) == 0 ? NULL :
518
mailbox_keywords_create_valid(dest_box, keywords_list);
520
save_ctx = mailbox_save_alloc(dest_trans);
521
mailbox_save_set_flags(save_ctx,
522
mail_get_flags(mail) & ~MAIL_DELETED,
524
ret = mailbox_copy(&save_ctx, mail);
525
mailbox_keywords_free(dest_box, &keywords);
527
if (ret < 0 && !mail->expunged)
532
if (mailbox_search_deinit(&search_ctx) < 0)
535
(void)mailbox_transaction_commit(&src_trans);
537
ret = mailbox_transaction_commit(&dest_trans);
539
mailbox_transaction_rollback(&dest_trans);
541
mailbox_close(&src_box);
542
mailbox_close(&dest_box);
545
ret = mailbox_list_delete_mailbox(list, src_name);
468
550
lazy_expunge_mailbox_list_delete(struct mailbox_list *list, const char *name)
470
552
struct lazy_expunge_mail_user *luser =
472
554
struct lazy_expunge_mailbox_list *llist =
473
555
LAZY_EXPUNGE_LIST_CONTEXT(list);
474
556
struct lazy_expunge_mail_storage *lstorage;
475
struct mailbox_list *dest_list;
557
struct mailbox_list *dest_list, *expunge_list;
476
558
enum mailbox_name_status status;
477
559
const char *destname;
479
561
char timestamp[256];
482
if (llist->storage == NULL) {
564
if (llist->storage == NULL || llist->deleting) {
483
565
/* not a maildir storage */
484
566
return llist->module_ctx.super.delete_mailbox(list, name);
506
/* destination mailbox name needs to contain a timestamp */
507
tm = localtime(&ioloop_time);
508
if (strftime(timestamp, sizeof(timestamp), "%Y%m%d-%H%M%S", tm) == 0)
509
i_strocpy(timestamp, dec2str(ioloop_time), sizeof(timestamp));
510
destname = t_strconcat(name, "-", timestamp, NULL);
588
expunge_list = luser->lazy_ns[LAZY_NAMESPACE_EXPUNGE]->storage->list;
589
dest_list = luser->lazy_ns[LAZY_NAMESPACE_DELETE]->storage->list;
591
if (expunge_list == dest_list) {
592
/* if there are no expunged messages in this mailbox,
593
we can simply rename the mailbox to the destination name */
596
/* destination mailbox name needs to contain a timestamp */
597
tm = localtime(&ioloop_time);
598
if (strftime(timestamp, sizeof(timestamp),
599
"%Y%m%d-%H%M%S", tm) == 0) {
600
i_strocpy(timestamp, dec2str(ioloop_time),
603
destname = t_strconcat(name, "-", timestamp, NULL);
512
606
/* first move the actual mailbox */
513
dest_list = luser->lazy_ns[LAZY_NAMESPACE_DELETE]->storage->list;
514
607
if ((ret = mailbox_move(list, name, dest_list, &destname)) < 0)
615
if (expunge_list == dest_list && strcmp(destname, name) != 0) {
616
llist->deleting = TRUE;
617
(void)mailbox_move_all_mails(dest_list, destname, name);
618
llist->deleting = FALSE;
522
621
/* next move the expunged messages mailbox, if it exists */
523
list = luser->lazy_ns[LAZY_NAMESPACE_EXPUNGE]->storage->list;
525
luser->lazy_ns[LAZY_NAMESPACE_DELETE_EXPUNGE]->storage->list;
526
(void)mailbox_move(list, name, dest_list, &destname);
622
dest_list = luser->lazy_ns[LAZY_NAMESPACE_DELETE_EXPUNGE]->storage->list;
623
if (expunge_list != dest_list)
624
(void)mailbox_move(expunge_list, name, dest_list, &destname);