~james-page/ubuntu/raring/dovecot/autopkgtest

« back to all changes in this revision

Viewing changes to src/lib-storage/index/maildir/maildir-sync-index.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2012-06-11 11:11:54 UTC
  • mfrom: (1.15.2) (4.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120611111154-678cwbdj6ktgsv1h
Tags: 1:2.1.7-1ubuntu1
* Merge from Debian unstable, remaining changes:
  + Add mail-stack-delivery package:
    - Update d/rules
    - d/control: convert existing dovecot-postfix package to a dummy
      package and add new mail-stack-delivery package.
    - Update maintainer scripts.
    - Rename d/dovecot-postfix.* to debian/mail-stack-delivery.*
    - d/mail-stack-delivery.preinst: Move previously installed backups and
      config files to a new package namespace.
    - d/mail-stack-delivery.prerm: Added to handle downgrades.
  + Use Snakeoil SSL certificates by default:
    - d/control: Depend on ssl-cert.
    - d/dovecot-core.postinst: Relax grep for SSL_* a bit.
  + Add autopkgtest to debian/tests/*.
  + Add ufw integration:
    - d/dovecot-core.ufw.profile: new ufw profile.
    - d/rules: install profile in dovecot-core.
    - d/control: dovecot-core - suggest ufw.
  + d/{control,rules}: enable PIE hardening.
  + d/dovecot-core.dirs: Added usr/share/doc/dovecot-core
  + Add apport hook:
    - d/rules, d/source_dovecot.py
  + Add upstart job:
    - d/rules, d/dovecot-core.dovecot.upstart, d/control,
      d/dovecot-core.dirs, dovecot-imapd.{postrm, postinst, prerm},
      d/dovecot-pop3d.{postinst, postrm, prerm}.
      d/mail-stack-deliver.postinst: Convert init script to upstart.
  + d/control: Added Pre-Depends: dpkg (>= 1.15.6) to dovecot-dbg to support
    xz compression in Ubuntu.
  + d/control: Demote dovecot-common Recommends: to Suggests: to prevent
    install of extra packages on upgrade.
  + d/patches/dovecot-drac.patch: Updated with version for dovecot >= 2.0.0.
  + d/control: Drop B-D on systemd.
* Dropped changes:
  + d/patches/fix-racey-restart.patch: part of 2.1.x, no longer required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2007-2011 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2007-2012 Dovecot authors, see the included COPYING file */
2
2
 
3
3
#include "lib.h"
4
4
#include "ioloop.h"
5
5
#include "array.h"
6
 
#include "hex-binary.h"
7
6
#include "maildir-storage.h"
8
7
#include "index-sync-changes.h"
9
8
#include "maildir-uidlist.h"
10
9
#include "maildir-keywords.h"
11
 
#include "maildir-filename.h"
 
10
#include "maildir-filename-flags.h"
12
11
#include "maildir-sync.h"
13
12
 
14
13
#include <stdio.h>
51
50
static bool
52
51
maildir_expunge_is_valid_guid(struct maildir_index_sync_context *ctx,
53
52
                              uint32_t uid, const char *filename,
54
 
                              uint8_t expunged_guid_128[MAIL_GUID_128_SIZE])
 
53
                              guid_128_t expunged_guid_128)
55
54
{
56
 
        uint8_t guid_128[MAIL_GUID_128_SIZE];
 
55
        guid_128_t guid_128;
57
56
        const char *guid;
58
57
 
59
 
        if (mail_guid_128_is_empty(expunged_guid_128)) {
 
58
        if (guid_128_is_empty(expunged_guid_128)) {
60
59
                /* no GUID associated with expunge */
61
60
                return TRUE;
62
61
        }
75
74
        mail_storage_set_critical(&ctx->mbox->storage->storage,
76
75
                "Mailbox %s: Expunged GUID mismatch for UID %u: %s vs %s",
77
76
                ctx->mbox->box.vname, ctx->uid,
78
 
                binary_to_hex(guid_128, sizeof(guid_128)),
79
 
                binary_to_hex(expunged_guid_128, MAIL_GUID_128_SIZE));
 
77
                guid_128_to_string(guid_128),
 
78
                guid_128_to_string(expunged_guid_128));
80
79
        return FALSE;
81
80
}
82
81
 
123
122
        i_assert(*fname != '\0');
124
123
 
125
124
        /* get the current flags and keywords */
126
 
        maildir_filename_get_flags(ctx->keywords_sync_ctx,
 
125
        maildir_filename_flags_get(ctx->keywords_sync_ctx,
127
126
                                   fname, &ctx->flags, &ctx->keywords);
128
127
 
129
128
        /* apply changes */
133
132
        ctx->flags = flags8;
134
133
 
135
134
        /* and try renaming with the new name */
136
 
        newfname = maildir_filename_set_flags(ctx->keywords_sync_ctx, fname,
 
135
        newfname = maildir_filename_flags_set(ctx->keywords_sync_ctx, fname,
137
136
                                              ctx->flags, &ctx->keywords);
138
137
        newpath = t_strconcat(dir, newfname, NULL);
139
138
        if (strcmp(path, newpath) == 0) {
206
205
        maildir_uidlist_sync_finish(ctx->uidlist_sync_ctx);
207
206
 
208
207
        i_warning("Maildir %s: Expunged message reappeared, giving a new UID "
209
 
                  "(old uid=%u, file=%s)%s", ctx->mbox->box.path,
 
208
                  "(old uid=%u, file=%s)%s", mailbox_get_path(&ctx->mbox->box),
210
209
                  uid, filename, strncmp(filename, "msg.", 4) != 0 ? "" :
211
210
                  " (Your MDA is saving MH files into Maildir?)");
212
211
        return 0;
244
243
                maildir_keywords_sync_init(mbox->keywords, _box->index);
245
244
        ctx->sync_changes =
246
245
                index_sync_changes_init(ctx->sync_ctx, ctx->view, ctx->trans,
247
 
                                        mbox->box.backend_readonly);
 
246
                                        maildir_is_backend_readonly(mbox));
248
247
        ctx->start_time = time(NULL);
249
248
 
250
249
        *ctx_r = ctx;
278
277
maildir_sync_index_update_ext_header(struct maildir_index_sync_context *ctx)
279
278
{
280
279
        struct maildir_mailbox *mbox = ctx->mbox;
 
280
        const char *cur_path;
281
281
        const void *data;
282
282
        size_t data_size;
283
283
        struct stat st;
284
284
 
285
 
        if (ctx->update_maildir_hdr_cur &&
286
 
            stat(t_strconcat(mbox->box.path, "/cur", NULL), &st) == 0) {
 
285
        cur_path = t_strconcat(mailbox_get_path(&mbox->box), "/cur", NULL);
 
286
        if (ctx->update_maildir_hdr_cur && stat(cur_path, &st) == 0) {
287
287
                if ((time_t)mbox->maildir_hdr.cur_check_time < st.st_mtime)
288
288
                        mbox->maildir_hdr.cur_check_time = st.st_mtime;
289
289
                mbox->maildir_hdr.cur_mtime = st.st_mtime;
312
312
                i_warning("Maildir %s: Synchronization took %u seconds "
313
313
                          "(%u new msgs, %u flag change attempts, "
314
314
                          "%u expunge attempts)",
315
 
                          ctx->mbox->box.path, time_diff,
 
315
                          mailbox_get_path(&ctx->mbox->box), time_diff,
316
316
                          ctx->new_msgs_count, ctx->flag_change_count,
317
317
                          ctx->expunge_count);
318
318
        }
465
465
        unsigned int changes = 0;
466
466
        int ret = 0;
467
467
        time_t time_before_sync;
468
 
        uint8_t expunged_guid_128[MAIL_GUID_128_SIZE];
 
468
        guid_128_t expunged_guid_128;
 
469
        enum mail_flags private_flags_mask;
469
470
        bool expunged, full_rescan = FALSE;
470
471
 
471
472
        i_assert(!mbox->syncing_commit);
479
480
                   first time, reset the index so we can add all messages as
480
481
                   new */
481
482
                i_warning("Maildir %s: UIDVALIDITY changed (%u -> %u)",
482
 
                          mbox->box.path, hdr->uid_validity, uid_validity);
 
483
                          mailbox_get_path(&ctx->mbox->box),
 
484
                          hdr->uid_validity, uid_validity);
483
485
                mail_index_reset(trans);
484
486
                index_mailbox_reset_uidvalidity(&mbox->box);
485
487
 
490
492
        }
491
493
        hdr_next_uid = hdr->next_uid;
492
494
 
 
495
        ctx->mbox->box.tmp_sync_view = view;
 
496
        private_flags_mask = mailbox_get_private_flags_mask(&mbox->box);
493
497
        time_before_sync = time(NULL);
494
498
        mbox->syncing_commit = TRUE;
495
499
        seq = prev_uid = 0; first_recent_uid = I_MAX(hdr->first_recent_uid, 1);
497
501
        i_array_init(&ctx->idx_keywords, MAILDIR_MAX_KEYWORDS);
498
502
        iter = maildir_uidlist_iter_init(mbox->uidlist);
499
503
        while (maildir_uidlist_iter_next(iter, &uid, &uflags, &filename)) {
500
 
                maildir_filename_get_flags(ctx->keywords_sync_ctx, filename,
 
504
                maildir_filename_flags_get(ctx->keywords_sync_ctx, filename,
501
505
                                           &ctx->flags, &ctx->keywords);
502
506
 
503
507
                i_assert(uid > prev_uid);
505
509
 
506
510
                /* the private flags are kept only in indexes. don't use them
507
511
                   at all even for newly seen mails */
508
 
                ctx->flags &= ~mbox->box.private_flags_mask;
 
512
                ctx->flags &= ~private_flags_mask;
509
513
 
510
514
        again:
511
515
                seq++;
580
584
                }
581
585
 
582
586
                /* the private flags are stored only in indexes, keep them */
583
 
                ctx->flags |= rec->flags & mbox->box.private_flags_mask;
 
587
                ctx->flags |= rec->flags & private_flags_mask;
584
588
 
585
589
                if (index_sync_changes_have(ctx->sync_changes)) {
586
590
                        /* apply flag changes to maildir */
644
648
 
645
649
        if (mbox->box.v.sync_notify != NULL)
646
650
                mbox->box.v.sync_notify(&mbox->box, 0, 0);
 
651
        ctx->mbox->box.tmp_sync_view = NULL;
647
652
 
648
653
        /* check cur/ mtime later. if we came here from saving messages they
649
654
           could still be moved to cur/ directory. */
682
687
        return ret < 0 ? -1 : (full_rescan ? 0 : 1);
683
688
}
684
689
 
685
 
static unsigned int maildir_list_get_ext_id(struct maildir_storage *storage,
686
 
                                            struct mail_index_view *view)
 
690
static unsigned int
 
691
maildir_list_get_ext_id(struct maildir_mailbox *mbox,
 
692
                        struct mail_index_view *view)
687
693
{
688
 
        if (storage->maildir_list_ext_id == (uint32_t)-1) {
689
 
                storage->maildir_list_ext_id =
 
694
        if (mbox->maildir_list_index_ext_id == (uint32_t)-1) {
 
695
                mbox->maildir_list_index_ext_id =
690
696
                        mail_index_ext_register(mail_index_view_get_index(view),
691
697
                                "maildir", 0,
692
698
                                sizeof(struct maildir_list_index_record),
693
699
                                sizeof(uint32_t));
694
700
        }
695
 
        return storage->maildir_list_ext_id;
 
701
        return mbox->maildir_list_index_ext_id;
696
702
}
697
703
 
698
704
int maildir_list_index_has_changed(struct mailbox *box,
706
712
        struct stat st;
707
713
        uint32_t ext_id;
708
714
        bool expunged;
709
 
 
710
 
        ext_id = maildir_list_get_ext_id(mbox->storage, list_view);
 
715
        int ret;
 
716
 
 
717
        ret = index_storage_list_index_has_changed(box, list_view, seq);
 
718
        if (ret != 0)
 
719
                return ret;
 
720
        if (mbox->storage->set->maildir_very_dirty_syncs)
 
721
                return 0;
 
722
 
 
723
        ext_id = maildir_list_get_ext_id(mbox, list_view);
711
724
        mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged);
712
725
        rec = data;
713
726
 
742
755
        return 0;
743
756
}
744
757
 
745
 
int maildir_list_index_update_sync(struct mailbox *box,
746
 
                                   struct mail_index_transaction *trans,
747
 
                                   uint32_t seq)
 
758
void maildir_list_index_update_sync(struct mailbox *box,
 
759
                                    struct mail_index_transaction *trans,
 
760
                                    uint32_t seq)
748
761
{
749
762
        struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
750
763
        struct mail_index_view *list_view;
755
768
        uint32_t ext_id;
756
769
        bool expunged;
757
770
 
 
771
        index_storage_list_index_update_sync(box, trans, seq);
 
772
        if (mbox->storage->set->maildir_very_dirty_syncs)
 
773
                return;
 
774
 
758
775
        /* get the current record */
759
776
        list_view = mail_index_transaction_get_view(trans);
760
 
        ext_id = maildir_list_get_ext_id(mbox->storage, list_view);
 
777
        ext_id = maildir_list_get_ext_id(mbox, list_view);
761
778
        mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged);
762
779
        if (expunged)
763
 
                return 0;
 
780
                return;
764
781
        old_rec = data;
765
782
 
766
783
        memset(&new_rec, 0, sizeof(new_rec));
773
790
        }
774
791
 
775
792
        if (old_rec == NULL ||
776
 
            memcmp(old_rec, &new_rec, sizeof(old_rec)) != 0) {
777
 
                mail_index_update_ext(trans, seq,
778
 
                                      mbox->storage->maildir_list_ext_id,
779
 
                                      &new_rec, NULL);
780
 
        }
781
 
        return 0;
 
793
            memcmp(old_rec, &new_rec, sizeof(*old_rec)) != 0)
 
794
                mail_index_update_ext(trans, seq, ext_id, &new_rec, NULL);
782
795
}