~ubuntu-branches/ubuntu/raring/dovecot/raring

« back to all changes in this revision

Viewing changes to pigeonhole/src/lib-sieve/plugins/ihave/ext-ihave-binary.c

  • Committer: Package Import Robot
  • Author(s): Marco Nenciarini
  • Date: 2011-09-19 19:26:48 UTC
  • mfrom: (1.14.4 upstream)
  • mto: (4.8.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 86.
  • Revision ID: package-import@ubuntu.com-20110919192648-ri3sovtiz334yori
Tags: 1:2.0.15-1
* [a22575a] New upstream version 2.0.15: (Closes: #642045)
    + doveadm altmove: Added -r parameter to move mails back to primary
      storage.
    - v2.0.14: Index reading could have eaten a lot of memory in some
      situations
    - doveadm index no longer affects future caching decisions
    - mbox: Fixed crash during mail delivery when mailbox didn't yet have
      GUID assigned to it.
    - zlib+mbox: Fetching last message from compressed mailboxes crashed.
    - lib-sql: Fixed load balancing and error
* [8ce5abc] Update pigeonhole to release 0.2.4
* [87658d2] Add dovecot-solr to dovecot-core's Suggests line.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2002-2011 Pigeonhole authors, see the included COPYING file
 
2
 */
 
3
 
 
4
#include "lib.h"
 
5
#include "str.h"
 
6
 
 
7
#include "sieve-common.h"
 
8
#include "sieve-extensions.h"
 
9
#include "sieve-error.h"
 
10
#include "sieve-script.h"
 
11
#include "sieve-binary.h"
 
12
#include "sieve-generator.h"
 
13
#include "sieve-interpreter.h"
 
14
#include "sieve-dump.h"
 
15
 
 
16
#include "ext-ihave-common.h"
 
17
#include "ext-ihave-binary.h"
 
18
 
 
19
/*
 
20
 * Forward declarations
 
21
 */
 
22
 
 
23
static bool ext_ihave_binary_save
 
24
        (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context);
 
25
static bool ext_ihave_binary_open
 
26
        (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context);
 
27
static bool ext_ihave_binary_up_to_date
 
28
        (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context);
 
29
 
 
30
/*
 
31
 * Binary include extension
 
32
 */
 
33
 
 
34
const struct sieve_binary_extension ihave_binary_ext = {
 
35
        &ihave_extension,
 
36
        ext_ihave_binary_save,
 
37
        ext_ihave_binary_open,
 
38
        NULL,
 
39
        ext_ihave_binary_up_to_date
 
40
};
 
41
 
 
42
/*
 
43
 * Binary context management
 
44
 */
 
45
 
 
46
struct ext_ihave_binary_context {
 
47
        struct sieve_binary *binary;
 
48
        struct sieve_binary_block *block;
 
49
 
 
50
        ARRAY_DEFINE(missing_extensions, const char *);
 
51
};
 
52
 
 
53
static struct ext_ihave_binary_context *ext_ihave_binary_create_context
 
54
(const struct sieve_extension *this_ext, struct sieve_binary *sbin)
 
55
{
 
56
        pool_t pool = sieve_binary_pool(sbin);
 
57
 
 
58
        struct ext_ihave_binary_context *ctx =
 
59
                p_new(pool, struct ext_ihave_binary_context, 1);
 
60
 
 
61
        ctx->binary = sbin;
 
62
        p_array_init(&ctx->missing_extensions, pool, 64);
 
63
 
 
64
        sieve_binary_extension_set(sbin, this_ext, &ihave_binary_ext, ctx);
 
65
        return ctx;
 
66
}
 
67
 
 
68
struct ext_ihave_binary_context *ext_ihave_binary_get_context
 
69
(const struct sieve_extension *this_ext, struct sieve_binary *sbin)
 
70
{
 
71
        struct ext_ihave_binary_context *ctx = (struct ext_ihave_binary_context *)
 
72
                sieve_binary_extension_get_context(sbin, this_ext);
 
73
 
 
74
        if ( ctx == NULL )
 
75
                ctx = ext_ihave_binary_create_context(this_ext, sbin);
 
76
 
 
77
        return ctx;
 
78
}
 
79
 
 
80
struct ext_ihave_binary_context *ext_ihave_binary_init
 
81
(const struct sieve_extension *this_ext, struct sieve_binary *sbin,
 
82
        struct sieve_ast *ast)
 
83
{
 
84
        struct ext_ihave_ast_context *ast_ctx =
 
85
                ext_ihave_get_ast_context(this_ext, ast);
 
86
        struct ext_ihave_binary_context *binctx;
 
87
        const char *const *exts;
 
88
        unsigned int i, count;
 
89
 
 
90
        binctx = ext_ihave_binary_get_context(this_ext, sbin);
 
91
 
 
92
        exts = array_get(&ast_ctx->missing_extensions, &count);
 
93
 
 
94
        if ( count > 0 ) {
 
95
                pool_t pool = sieve_binary_pool(sbin);
 
96
 
 
97
                if ( binctx->block == NULL )
 
98
                        binctx->block = sieve_binary_extension_create_block(sbin, this_ext);
 
99
 
 
100
                for ( i = 0; i < count; i++ ) {
 
101
                        const char *ext_name = p_strdup(pool, exts[i]);
 
102
 
 
103
                        array_append(&binctx->missing_extensions, &ext_name, 1);
 
104
                }
 
105
        }
 
106
 
 
107
        return binctx;
 
108
}
 
109
 
 
110
/*
 
111
 * Binary extension
 
112
 */
 
113
 
 
114
static bool ext_ihave_binary_save
 
115
(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context)
 
116
{
 
117
        struct ext_ihave_binary_context *binctx =
 
118
                (struct ext_ihave_binary_context *) context;
 
119
        const char *const *exts;
 
120
        unsigned int count, i;
 
121
 
 
122
        exts = array_get(&binctx->missing_extensions, &count);
 
123
 
 
124
        if ( binctx->block != NULL )
 
125
                sieve_binary_block_clear(binctx->block);
 
126
 
 
127
        if ( count > 0 ) {
 
128
                if ( binctx->block == NULL )
 
129
                        binctx->block = sieve_binary_extension_create_block(sbin, ext);
 
130
 
 
131
                sieve_binary_emit_unsigned(binctx->block, count);
 
132
 
 
133
                for ( i = 0; i < count; i++ ) {
 
134
                        sieve_binary_emit_cstring(binctx->block, exts[i]);
 
135
                }
 
136
        }
 
137
 
 
138
        return TRUE;
 
139
}
 
140
 
 
141
static bool ext_ihave_binary_open
 
142
(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context)
 
143
{
 
144
        struct sieve_instance *svinst = ext->svinst;
 
145
        struct ext_ihave_binary_context *binctx =
 
146
                (struct ext_ihave_binary_context *) context;
 
147
        struct sieve_binary_block *sblock;
 
148
        unsigned int i, count, block_id;
 
149
        sieve_size_t offset;
 
150
 
 
151
        sblock = sieve_binary_extension_get_block(sbin, ext);
 
152
 
 
153
        if ( sblock != NULL ) {
 
154
                binctx->block = sblock;
 
155
                block_id = sieve_binary_block_get_id(sblock);
 
156
 
 
157
                offset = 0;
 
158
 
 
159
                /* Read number of missing extensions to read subsequently */
 
160
                if ( !sieve_binary_read_unsigned(sblock, &offset, &count) ) {
 
161
                        sieve_sys_error(svinst,
 
162
                                "ihave: failed to read missing extension count "
 
163
                                "from block %d of binary %s", block_id, sieve_binary_path(sbin));
 
164
                        return FALSE;
 
165
                }
 
166
 
 
167
                /* Read dependencies */
 
168
                for ( i = 0; i < count; i++ ) {
 
169
                        string_t *ext_name;
 
170
                        const char *name;
 
171
 
 
172
                        if ( !sieve_binary_read_string(sblock, &offset, &ext_name) ) {
 
173
                                /* Binary is corrupt, recompile */
 
174
                                sieve_sys_error(svinst,
 
175
                                        "ihave: failed to read missing extension name "
 
176
                                        "from block %d of binary %s", block_id, sieve_binary_path(sbin));
 
177
                                return FALSE;
 
178
                        }
 
179
 
 
180
                        name = str_c(ext_name);
 
181
                        array_append(&binctx->missing_extensions, &name, 1);
 
182
                }
 
183
        }
 
184
 
 
185
        return TRUE;
 
186
}
 
187
 
 
188
static bool ext_ihave_binary_up_to_date
 
189
(const struct sieve_extension *ext, struct sieve_binary *sbin ATTR_UNUSED,
 
190
        void *context)
 
191
{
 
192
        struct ext_ihave_binary_context *binctx =
 
193
                (struct ext_ihave_binary_context *) context;
 
194
        const char *const *exts;
 
195
        unsigned int count, i;
 
196
 
 
197
        exts = array_get(&binctx->missing_extensions, &count);
 
198
        for ( i = 0; i < count; i++ ) {
 
199
                if ( sieve_extension_get_by_name(ext->svinst, exts[i]) != NULL )
 
200
                        return FALSE;
 
201
        }
 
202
 
 
203
        return TRUE;
 
204
}
 
205
 
 
206
/*
 
207
 * Main extension interface
 
208
 */
 
209
 
 
210
bool ext_ihave_binary_load
 
211
(const struct sieve_extension *ext, struct sieve_binary *sbin)
 
212
{
 
213
        (void)ext_ihave_binary_get_context(ext, sbin);
 
214
 
 
215
        return TRUE;
 
216
}
 
217
 
 
218
bool ext_ihave_binary_dump
 
219
(const struct sieve_extension *ext, struct sieve_dumptime_env *denv)
 
220
{
 
221
        struct sieve_binary *sbin = denv->sbin;
 
222
        struct ext_ihave_binary_context *binctx =
 
223
                ext_ihave_binary_get_context(ext, sbin);
 
224
        const char *const *exts;
 
225
        unsigned int count, i;
 
226
 
 
227
        exts = array_get(&binctx->missing_extensions, &count);
 
228
 
 
229
        if ( count > 0 ) {
 
230
                sieve_binary_dump_sectionf(denv,
 
231
                        "Extensions missing at compile (block: %d)",
 
232
                        sieve_binary_block_get_id(binctx->block));
 
233
 
 
234
                for ( i = 0; i < count; i++ ) {
 
235
                        sieve_binary_dumpf(denv, "  -  %s\n", exts[i]);
 
236
                }
 
237
        }
 
238
 
 
239
        return TRUE;
 
240
}