~ubuntu-branches/ubuntu/utopic/dovecot/utopic-proposed

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-08 09:35:49 UTC
  • mfrom: (4.1.35 sid)
  • Revision ID: package-import@ubuntu.com-20140108093549-i72o93pux8p0dlaf
Tags: 1:2.2.9-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/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.
  + Use the autotools-dev dh addon to update config.guess/config.sub for
    arm64.
* Dropped changes, included in Debian:
  - Update Dovecot name to reflect distribution in login greeting.
  - Update Drac plugin for >= 2.0.0 support.
* d/control: Drop dovecot-postfix package as its no longer required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */
2
2
 
3
3
#include "lib.h"
4
4
#include "ioloop.h"
135
135
        ctx->newdir = p_strconcat(pool, path, "/new", NULL);
136
136
        ctx->curdir = p_strconcat(pool, path, "/cur", NULL);
137
137
 
138
 
        buffer_create_const_data(&ctx->keywords_buffer, NULL, 0);
 
138
        buffer_create_from_const_data(&ctx->keywords_buffer, "", 0);
139
139
        array_create_from_buffer(&ctx->keywords_array, &ctx->keywords_buffer,
140
140
                                 sizeof(unsigned int));
141
141
        ctx->last_save_finished = TRUE;
147
147
                 struct mail *src_mail)
148
148
{
149
149
        struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
 
150
        struct mail_save_data *mdata = &_ctx->data;
150
151
        struct maildir_filename *mf;
151
152
        struct istream *input;
152
153
        unsigned int keyword_count;
155
156
 
156
157
        /* allow caller to specify recent flag only when uid is specified
157
158
           (we're replicating, converting, etc.). */
158
 
        if (_ctx->uid == 0)
159
 
                _ctx->flags |= MAIL_RECENT;
160
 
        else if ((_ctx->flags & MAIL_RECENT) == 0 &&
161
 
                 ctx->last_nonrecent_uid < _ctx->uid)
162
 
                ctx->last_nonrecent_uid = _ctx->uid;
 
159
        if (mdata->uid == 0)
 
160
                mdata->flags |= MAIL_RECENT;
 
161
        else if ((mdata->flags & MAIL_RECENT) == 0 &&
 
162
                 ctx->last_nonrecent_uid < mdata->uid)
 
163
                ctx->last_nonrecent_uid = mdata->uid;
163
164
 
164
165
        /* now, we want to be able to rollback the whole append session,
165
166
           so we'll just store the name of this temp file and move it later
166
167
           into new/ or cur/. */
167
168
        /* @UNSAFE */
168
 
        keyword_count = _ctx->keywords == NULL ? 0 : _ctx->keywords->count;
 
169
        keyword_count = mdata->keywords == NULL ? 0 : mdata->keywords->count;
169
170
        mf = p_malloc(ctx->pool, sizeof(*mf) +
170
171
                      sizeof(unsigned int) * keyword_count);
171
172
        mf->tmp_name = mf->dest_basename = p_strdup(ctx->pool, tmp_fname);
172
 
        mf->flags = _ctx->flags;
 
173
        mf->flags = mdata->flags;
173
174
        mf->size = (uoff_t)-1;
174
175
        mf->vsize = (uoff_t)-1;
175
176
 
179
180
        ctx->files_tail = &mf->next;
180
181
        ctx->files_count++;
181
182
 
182
 
        if (_ctx->keywords != NULL) {
 
183
        if (mdata->keywords != NULL) {
183
184
                /* @UNSAFE */
184
185
                mf->keywords_count = keyword_count;
185
 
                memcpy(mf + 1, _ctx->keywords->idx,
 
186
                memcpy(mf + 1, mdata->keywords->idx,
186
187
                       sizeof(unsigned int) * keyword_count);
187
188
                ctx->have_keywords = TRUE;
188
189
        }
189
 
        if (_ctx->pop3_uidl != NULL)
190
 
                mf->pop3_uidl = p_strdup(ctx->pool, _ctx->pop3_uidl);
191
 
        mf->pop3_order = _ctx->pop3_order;
 
190
        if (mdata->pop3_uidl != NULL)
 
191
                mf->pop3_uidl = p_strdup(ctx->pool, mdata->pop3_uidl);
 
192
        mf->pop3_order = mdata->pop3_order;
192
193
 
193
194
        /* insert into index */
194
 
        mail_index_append(ctx->trans, _ctx->uid, &ctx->seq);
 
195
        mail_index_append(ctx->trans, mdata->uid, &ctx->seq);
195
196
        mail_index_update_flags(ctx->trans, ctx->seq,
196
 
                                MODIFY_REPLACE, _ctx->flags & ~MAIL_RECENT);
197
 
        if (_ctx->keywords != NULL) {
 
197
                                MODIFY_REPLACE, mdata->flags & ~MAIL_RECENT);
 
198
        if (mdata->keywords != NULL) {
198
199
                mail_index_update_keywords(ctx->trans, ctx->seq,
199
 
                                           MODIFY_REPLACE, _ctx->keywords);
 
200
                                           MODIFY_REPLACE, mdata->keywords);
200
201
        }
201
 
        if (_ctx->min_modseq != 0) {
 
202
        if (mdata->min_modseq != 0) {
202
203
                mail_index_update_modseq(ctx->trans, ctx->seq,
203
 
                                         _ctx->min_modseq);
 
204
                                         mdata->min_modseq);
204
205
        }
205
206
 
206
207
        if (ctx->first_seq == 0) {
272
273
                        return TRUE;
273
274
                }
274
275
 
275
 
                *fname_r = maildir_filename_flags_set(NULL, basename,
276
 
                                        mf->flags & MAIL_FLAGS_MASK, NULL);
 
276
                *fname_r = maildir_filename_flags_set(basename,
 
277
                                        mf->flags & MAIL_FLAGS_MASK);
277
278
                return FALSE;
278
279
        }
279
280
 
280
281
        i_assert(ctx->keywords_sync_ctx != NULL || mf->keywords_count == 0);
281
 
        buffer_create_const_data(&ctx->keywords_buffer, mf + 1,
282
 
                                 mf->keywords_count * sizeof(unsigned int));
283
 
        *fname_r = maildir_filename_flags_set(ctx->keywords_sync_ctx, basename,
284
 
                                              mf->flags & MAIL_FLAGS_MASK,
285
 
                                              &ctx->keywords_array);
 
282
        buffer_create_from_const_data(&ctx->keywords_buffer, mf + 1,
 
283
                                      mf->keywords_count * sizeof(unsigned int));
 
284
        *fname_r = maildir_filename_flags_kw_set(ctx->keywords_sync_ctx,
 
285
                                                 basename,
 
286
                                                 mf->flags & MAIL_FLAGS_MASK,
 
287
                                                 &ctx->keywords_array);
286
288
        return FALSE;
287
289
}
288
290
 
411
413
                        else
412
414
                                ctx->input = i_stream_create_lf(input);
413
415
                        mf = maildir_save_add(_ctx, fname, NULL);
414
 
                        if (_ctx->guid != NULL) {
 
416
                        if (_ctx->data.guid != NULL) {
415
417
                                maildir_save_set_dest_basename(_ctx, mf,
416
 
                                                               _ctx->guid);
 
418
                                                               _ctx->data.guid);
417
419
                        }
418
420
                }
419
421
        } T_END;
420
422
 
421
423
        if (!ctx->failed) {
422
 
                _ctx->output = o_stream_create_fd_file(ctx->fd, 0, FALSE);
423
 
                o_stream_cork(_ctx->output);
 
424
                _ctx->data.output = o_stream_create_fd_file(ctx->fd, 0, FALSE);
 
425
                o_stream_cork(_ctx->data.output);
424
426
                ctx->last_save_finished = FALSE;
425
427
        }
426
428
        return ctx->failed ? -1 : 0;
435
437
                return -1;
436
438
 
437
439
        do {
438
 
                if (o_stream_send_istream(_ctx->output, ctx->input) < 0) {
 
440
                if (o_stream_send_istream(_ctx->data.output, ctx->input) < 0) {
439
441
                        if (!mail_storage_set_error_from_errno(storage)) {
440
442
                                mail_storage_set_critical(storage,
441
443
                                        "o_stream_send_istream(%s/%s) "
462
464
        struct utimbuf buf;
463
465
        struct stat st;
464
466
 
465
 
        if (ctx->ctx.received_date != (time_t)-1) {
 
467
        if (ctx->ctx.data.received_date != (time_t)-1) {
466
468
                /* set the received_date by modifying mtime */
467
469
                buf.actime = ioloop_time;
468
 
                buf.modtime = ctx->ctx.received_date;
 
470
                buf.modtime = ctx->ctx.data.received_date;
469
471
 
470
472
                if (utime(path, &buf) < 0) {
471
473
                        mail_storage_set_critical(storage,
474
476
                }
475
477
        } else if (ctx->fd != -1) {
476
478
                if (fstat(ctx->fd, &st) == 0)
477
 
                        ctx->ctx.received_date = st.st_mtime;
 
479
                        ctx->ctx.data.received_date = st.st_mtime;
478
480
                else {
479
481
                        mail_storage_set_critical(storage,
480
482
                                                  "fstat(%s) failed: %m", path);
483
485
        } else {
484
486
                /* hardlinked */
485
487
                if (stat(path, &st) == 0)
486
 
                        ctx->ctx.received_date = st.st_mtime;
 
488
                        ctx->ctx.data.received_date = st.st_mtime;
487
489
                else {
488
490
                        mail_storage_set_critical(storage,
489
491
                                                  "stat(%s) failed: %m", path);
528
530
        }
529
531
 
530
532
        path = t_strconcat(ctx->tmpdir, "/", ctx->file_last->tmp_name, NULL);
531
 
        if (!ctx->failed && o_stream_flush(_ctx->output) < 0) {
 
533
        if (!ctx->failed && o_stream_nfinish(_ctx->data.output) < 0) {
532
534
                if (!mail_storage_set_error_from_errno(storage)) {
533
535
                        mail_storage_set_critical(storage,
534
 
                                "o_stream_flush(%s) failed: %m", path);
 
536
                                "write(%s) failed: %m", path);
535
537
                }
536
538
                ctx->failed = TRUE;
537
539
        }
538
540
 
539
 
        if (_ctx->save_date != (time_t)-1) {
 
541
        if (_ctx->data.save_date != (time_t)-1) {
540
542
                /* we can't change ctime, but we can add the date to cache */
541
543
                struct index_mail *mail = (struct index_mail *)_ctx->dest_mail;
542
 
                uint32_t t = _ctx->save_date;
 
544
                uint32_t t = _ctx->data.save_date;
543
545
 
544
546
                index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &t, sizeof(t));
545
547
        }
549
551
 
550
552
        if (ctx->cur_dest_mail != NULL) {
551
553
                index_mail_cache_parse_deinit(ctx->cur_dest_mail,
552
 
                                              ctx->ctx.received_date,
 
554
                                              ctx->ctx.data.received_date,
553
555
                                              !ctx->failed);
554
556
        }
555
557
        i_stream_unref(&ctx->input);
556
558
 
557
559
        /* remember the size in case we want to add it to filename */
558
 
        ctx->file_last->size = _ctx->output->offset;
 
560
        ctx->file_last->size = _ctx->data.output->offset;
559
561
        if (ctx->cur_dest_mail == NULL ||
560
562
            mail_get_virtual_size(ctx->cur_dest_mail,
561
563
                                  &ctx->file_last->vsize) < 0)
562
564
                ctx->file_last->vsize = (uoff_t)-1;
563
565
 
564
 
        output_errno = _ctx->output->stream_errno;
565
 
        o_stream_destroy(&_ctx->output);
 
566
        output_errno = _ctx->data.output->last_failed_errno;
 
567
        o_stream_destroy(&_ctx->data.output);
566
568
 
567
569
        if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER &&
568
570
            !ctx->failed) {
816
818
{
817
819
        uoff_t size;
818
820
 
819
 
        if (!ctx->locked_uidlist_refresh) {
 
821
        if (!ctx->locked_uidlist_refresh && ctx->locked) {
820
822
                (void)maildir_uidlist_refresh(ctx->mbox->uidlist);
821
823
                ctx->locked_uidlist_refresh = TRUE;
822
824
        }
823
825
 
824
 
        if ((prev_mf != NULL && maildir_filename_has_conflict(mf, prev_mf)) ||
 
826
        if (!ctx->locked_uidlist_refresh ||
 
827
            (prev_mf != NULL && maildir_filename_has_conflict(mf, prev_mf)) ||
825
828
            maildir_uidlist_get_full_filename(ctx->mbox->uidlist,
826
829
                                              mf->dest_basename) != NULL) {
827
830
                /* file already exists. give it another name.
851
854
static int
852
855
maildir_save_move_files_to_newcur(struct maildir_save_context *ctx)
853
856
{
854
 
        ARRAY_DEFINE(files, struct maildir_filename *);
 
857
        ARRAY(struct maildir_filename *) files;
855
858
        struct maildir_filename *mf, *const *mfp, *prev_mf;
856
859
        bool newdir, new_changed, cur_changed;
857
860
        int ret;
947
950
        enum maildir_uidlist_sync_flags sync_flags;
948
951
        int ret;
949
952
 
950
 
        i_assert(_ctx->output == NULL);
 
953
        i_assert(_ctx->data.output == NULL);
951
954
        i_assert(ctx->last_save_finished);
952
955
 
953
956
        if (ctx->files_count == 0) {
1063
1066
{
1064
1067
        struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
1065
1068
 
1066
 
        i_assert(_ctx->output == NULL);
 
1069
        i_assert(_ctx->data.output == NULL);
1067
1070
 
1068
1071
        if (!ctx->last_save_finished)
1069
1072
                maildir_save_cancel(&ctx->ctx);