~ubuntu-branches/ubuntu/wily/dovecot/wily

« back to all changes in this revision

Viewing changes to src/plugins/virtual/virtual-search.c

  • Committer: Bazaar Package Importer
  • Author(s): CHuck Short, Chuck Short
  • Date: 2009-11-06 00:47:29 UTC
  • mfrom: (4.1.9 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091106004729-i39n7v9e7d4h51f6
Tags: 1:1.2.6-1ubuntu1
* Merge from debian testing, remaining changes:
  Add new binary pkg dovecot-postfix that integrates postfix and dovecot
  automatically: (LP: #164837)
  + debian/control:
    - add new binary with short description
    - set Architecture all for dovecot-postfix (LP: #329878)
  + debian/dovecot-postfix.postinst:
    - create initial certificate symlinks to snakeoil.
    - set up postfix with postconf to:
      - use Maildir/ as the default mailbox.
      - use dovecot as the sasl authentication server.
      - use dovecot LDA (deliver).
      - use tls for smtp{d} services.
    - fix certificates paths in postfix' main.cf
    - add reject_unauth_destination to postfix' recipient restrictions
    - add reject_unknown_sender_domain to postfix' sender restrictions
    - rename configuration name on remove, delete on purge
    - restart dovecot after linking certificates
    - handle use case when postfix is unconfigurated
   + debian/dovecot-postfix.dirs: create backup directory for postfix's configuration
   + restart postfix and dovecot.
   + debian/dovecot-postfix.postrm:
     - remove all dovecot related configuration from postfix.
     - restart postfix and dovecot.
   + debian/dovecot-common.init:
     - check if /etc/dovecot/dovecot-postfix.conf exists and use it
       as the configuration file if so.
   + debian/patches/warning-ubuntu-postfix.dpatch
     - add warning about dovecot-postfix.conf in dovecot default 
       configuration file
   + debian/patches/dovecot-postfix.conf.diff:
     - Ubuntu server custom changes to the default dovecot configuration for
       better interfation with postfix
     - enable sieve plugin
   + debian/patches/dovecot-postfix.conf.diff:
     + Ubuntu server custom changes to the default dovecot configuration for
       better integration with postfix:
       - enable imap, pop3, imaps, pop3s and managesieve by default.
       - enable dovecot LDA (deliver).
       - enable SASL auth socket in postfix private directory.
   + debian/rules:
     - copy, patch and install dovecot-postfix.conf in /etc/dovecot/.
     - build architecure independent packages too
   + Use Snakeoil SSL certificates by default.
     - debian/control: Depend on ssl-cert.
     - debian/patches/ssl-cert-snakeoil.dpatch: Change default SSL cert
       paths to snakeoil.
     - debian/dovecot-common.postinst: Relax grep for SSL_* a bit.
   + Add autopkgtest to debian/tests/*.
   + Fast TearDown: Update the lsb init header to not stop in level 6.
   + Add ufw integration:
     - Created debian/dovecot-common.ufw.profile.
     - debian/rules:
       + install profile
     - debian/control:
       + Suggest ufw
   + debian/{control,rules}: enable PIE hardening.
   + dovecot-imapd, dovecot-pop3: Replaces dovecot-common (<< 1:1.1). LP: #254721
   + debian/control:
     - Update Vcs-* headers.
   + debian/rules:
     - Create emtpy stamp.h.in files in dovecot-sieve/ and dovecot-managesieve/
       if they're not there since empty files are not included in the diff.gz 
       file.
   + Add SMTP-AUTH support for Outlook (login auth mechanism)
   + Dropped:
     - debian/patches/security-CVE-2009-3235: Applied upstream.
     - debian/patches/fix-pop3-assertion.dpatch: Applied upstream.
     - dovecot-sieve and dovecot-managesieve: Use the debian patches instead.

  [Chuck Short]
  - Updated dovecot-sieve to 0.1.13.
  - Updated dovecot-managesieve to 0.11.9.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2008-2009 Dovecot authors, see the included COPYING file */
 
2
 
 
3
#include "lib.h"
 
4
#include "array.h"
 
5
#include "mail-search.h"
 
6
#include "index-storage.h"
 
7
#include "virtual-storage.h"
 
8
 
 
9
#include <stdlib.h>
 
10
 
 
11
enum virtual_search_state {
 
12
        VIRTUAL_SEARCH_STATE_FAILED = -1,
 
13
        VIRTUAL_SEARCH_STATE_BUILD,
 
14
        VIRTUAL_SEARCH_STATE_RETURN,
 
15
        VIRTUAL_SEARCH_STATE_SORT,
 
16
        VIRTUAL_SEARCH_STATE_SORT_DONE
 
17
};
 
18
 
 
19
struct virtual_search_record {
 
20
        uint32_t mailbox_id;
 
21
        uint32_t real_uid;
 
22
        uint32_t virtual_seq;
 
23
};
 
24
 
 
25
struct virtual_search_context {
 
26
        union mail_search_module_context module_ctx;
 
27
 
 
28
        ARRAY_TYPE(seq_range) result;
 
29
        struct seq_range_iter result_iter;
 
30
        ARRAY_DEFINE(records, struct virtual_search_record);
 
31
 
 
32
        enum virtual_search_state search_state;
 
33
        unsigned int next_result_n;
 
34
        unsigned int next_record_idx;
 
35
};
 
36
 
 
37
static int virtual_search_record_cmp(const void *p1, const void *p2)
 
38
{
 
39
        const struct virtual_search_record *r1 = p1, *r2 = p2;
 
40
 
 
41
        if (r1->mailbox_id < r2->mailbox_id)
 
42
                return -1;
 
43
        if (r1->mailbox_id > r2->mailbox_id)
 
44
                return 1;
 
45
 
 
46
        if (r1->real_uid < r2->real_uid)
 
47
                return -1;
 
48
        if (r1->real_uid > r2->real_uid)
 
49
                return 1;
 
50
        return 0;
 
51
}
 
52
 
 
53
static int mail_search_get_result(struct mail_search_context *ctx)
 
54
{
 
55
        const struct mail_search_arg *arg;
 
56
        int ret = 1;
 
57
 
 
58
        for (arg = ctx->args->args; arg != NULL; arg = arg->next) {
 
59
                if (arg->result < 0)
 
60
                        return -1;
 
61
                if (arg->result == 0)
 
62
                        ret = 0;
 
63
        }
 
64
        return ret;
 
65
}
 
66
 
 
67
static int virtual_search_get_records(struct mail_search_context *ctx,
 
68
                                      struct virtual_search_context *vctx)
 
69
{
 
70
        struct virtual_mailbox *mbox =
 
71
                (struct virtual_mailbox *)ctx->transaction->box;
 
72
        const struct virtual_mail_index_record *vrec;
 
73
        struct virtual_search_record srec, *srecs;
 
74
        unsigned int count;
 
75
        const void *data;
 
76
        bool expunged;
 
77
        int ret, result;
 
78
 
 
79
        memset(&srec, 0, sizeof(srec));
 
80
        while ((ret = index_storage_search_next_update_seq(ctx)) > 0) {
 
81
                result = mail_search_get_result(ctx);
 
82
                i_assert(result != 0);
 
83
                if (result > 0) {
 
84
                        /* full match, no need to check this any further */
 
85
                        seq_range_array_add(&vctx->result, 0, ctx->seq);
 
86
                } else {
 
87
                        /* possible match, save and check later */
 
88
                        mail_index_lookup_ext(mbox->ibox.view, ctx->seq,
 
89
                                              mbox->virtual_ext_id,
 
90
                                              &data, &expunged);
 
91
                        vrec = data;
 
92
 
 
93
                        srec.mailbox_id = vrec->mailbox_id;
 
94
                        srec.real_uid = vrec->real_uid;
 
95
                        srec.virtual_seq = ctx->seq;
 
96
                        array_append(&vctx->records, &srec, 1);
 
97
                }
 
98
                mail_search_args_reset(ctx->args->args, FALSE);
 
99
        }
 
100
        srecs = array_get_modifiable(&vctx->records, &count);
 
101
        qsort(srecs, count, sizeof(*srecs), virtual_search_record_cmp);
 
102
 
 
103
        ctx->progress_max = count;
 
104
        return ret;
 
105
}
 
106
 
 
107
struct mail_search_context *
 
108
virtual_search_init(struct mailbox_transaction_context *t,
 
109
                    struct mail_search_args *args,
 
110
                    const enum mail_sort_type *sort_program)
 
111
{
 
112
        struct mail_search_context *ctx;
 
113
        struct virtual_search_context *vctx;
 
114
 
 
115
        ctx = index_storage_search_init(t, args, sort_program);
 
116
 
 
117
        vctx = i_new(struct virtual_search_context, 1);
 
118
        vctx->search_state = VIRTUAL_SEARCH_STATE_BUILD;
 
119
        i_array_init(&vctx->result, 64);
 
120
        i_array_init(&vctx->records, 64);
 
121
        MODULE_CONTEXT_SET(ctx, virtual_storage_module, vctx);
 
122
 
 
123
        if (virtual_search_get_records(ctx, vctx) < 0)
 
124
                vctx->search_state = VIRTUAL_SEARCH_STATE_FAILED;
 
125
 
 
126
        seq_range_array_iter_init(&vctx->result_iter, &vctx->result);
 
127
        return ctx;
 
128
}
 
129
 
 
130
int virtual_search_deinit(struct mail_search_context *ctx)
 
131
{
 
132
        struct virtual_search_context *vctx = VIRTUAL_CONTEXT(ctx);
 
133
 
 
134
        array_free(&vctx->result);
 
135
        array_free(&vctx->records);
 
136
        i_free(vctx);
 
137
        return index_storage_search_deinit(ctx);
 
138
}
 
139
 
 
140
int virtual_search_next_nonblock(struct mail_search_context *ctx,
 
141
                                 struct mail *mail, bool *tryagain_r)
 
142
{
 
143
        struct virtual_search_context *vctx = VIRTUAL_CONTEXT(ctx);
 
144
        uint32_t seq;
 
145
        int ret;
 
146
 
 
147
        switch (vctx->search_state) {
 
148
        case VIRTUAL_SEARCH_STATE_FAILED:
 
149
                return -1;
 
150
        case VIRTUAL_SEARCH_STATE_BUILD:
 
151
                if (ctx->sort_program == NULL)
 
152
                        vctx->search_state = VIRTUAL_SEARCH_STATE_SORT;
 
153
                else
 
154
                        vctx->search_state = VIRTUAL_SEARCH_STATE_RETURN;
 
155
                return virtual_search_next_nonblock(ctx, mail, tryagain_r);
 
156
        case VIRTUAL_SEARCH_STATE_RETURN:
 
157
                return index_storage_search_next_nonblock(ctx, mail, tryagain_r);
 
158
        case VIRTUAL_SEARCH_STATE_SORT:
 
159
                /* the messages won't be returned sorted, so we'll have to
 
160
                   do it ourself */
 
161
                while ((ret = index_storage_search_next_nonblock(ctx, mail,
 
162
                                                        tryagain_r)) > 0)
 
163
                        seq_range_array_add(&vctx->result, 0, mail->seq);
 
164
                if (ret < 0 || *tryagain_r)
 
165
                        return ret;
 
166
 
 
167
                vctx->next_result_n = 0;
 
168
                vctx->search_state = VIRTUAL_SEARCH_STATE_SORT_DONE;
 
169
                /* fall through */
 
170
        case VIRTUAL_SEARCH_STATE_SORT_DONE:
 
171
                *tryagain_r = FALSE;
 
172
                if (!seq_range_array_iter_nth(&vctx->result_iter,
 
173
                                              vctx->next_result_n, &seq))
 
174
                        return 0;
 
175
                vctx->next_result_n++;
 
176
                mail_set_seq(mail, seq);
 
177
                return 1;
 
178
        }
 
179
        i_unreached();
 
180
}
 
181
 
 
182
static void search_args_set_full_match(struct mail_search_arg *args)
 
183
{
 
184
        for (; args != NULL; args = args->next)
 
185
                args->result = 1;
 
186
}
 
187
 
 
188
bool virtual_search_next_update_seq(struct mail_search_context *ctx)
 
189
{
 
190
        struct virtual_search_context *vctx = VIRTUAL_CONTEXT(ctx);
 
191
        const struct virtual_search_record *recs;
 
192
        unsigned int count;
 
193
 
 
194
        recs = array_get(&vctx->records, &count);
 
195
        if (vctx->next_record_idx < count) {
 
196
                /* go through potential results first */
 
197
                ctx->seq = recs[vctx->next_record_idx++].virtual_seq - 1;
 
198
                if (!index_storage_search_next_update_seq(ctx))
 
199
                        i_unreached();
 
200
                ctx->progress_cur = vctx->next_record_idx;
 
201
                return TRUE;
 
202
        }
 
203
 
 
204
        if (ctx->sort_program != NULL &&
 
205
            seq_range_array_iter_nth(&vctx->result_iter,
 
206
                                     vctx->next_result_n, &ctx->seq)) {
 
207
                /* this is known to match fully */
 
208
                search_args_set_full_match(ctx->args->args);
 
209
                vctx->next_result_n++;
 
210
                return TRUE;
 
211
        }
 
212
        return FALSE;
 
213
}