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

« back to all changes in this revision

Viewing changes to pigeonhole/src/lib-sieve/plugins/imap4flags/tag-flags.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 Pigeonhole authors, see the included COPYING file
 
1
/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file
2
2
 */
3
3
 
4
4
#include "lib.h"
11
11
#include "sieve-extensions.h"
12
12
#include "sieve-commands.h"
13
13
#include "sieve-result.h"
14
 
#include "sieve-validator.h" 
 
14
#include "sieve-validator.h"
15
15
#include "sieve-generator.h"
16
16
#include "sieve-interpreter.h"
17
17
#include "sieve-actions.h"
21
21
 
22
22
#include <ctype.h>
23
23
 
24
 
/* 
 
24
/*
25
25
 * Flags tagged argument
26
26
 */
27
27
 
28
28
static bool tag_flags_validate
29
 
        (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
 
29
        (struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
30
30
                struct sieve_command *cmd);
31
31
static bool tag_flags_validate_persistent
32
32
        (struct sieve_validator *valdtr, struct sieve_command *cmd,
35
35
        (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
36
36
                struct sieve_command *cmd);
37
37
 
38
 
const struct sieve_argument_def tag_flags = { 
39
 
        "flags", 
40
 
        NULL, 
41
 
        tag_flags_validate, 
 
38
const struct sieve_argument_def tag_flags = {
 
39
        "flags",
 
40
        NULL,
 
41
        tag_flags_validate,
42
42
        NULL, NULL,
43
 
        tag_flags_generate 
44
 
};
45
 
 
46
 
const struct sieve_argument_def tag_flags_implicit = { 
47
 
        "flags-implicit", 
48
 
        NULL,   NULL, NULL, 
49
 
        tag_flags_validate_persistent, 
50
 
        tag_flags_generate
51
 
};
52
 
 
53
 
/* 
54
 
 * Side effect 
 
43
        tag_flags_generate
 
44
};
 
45
 
 
46
const struct sieve_argument_def tag_flags_implicit = {
 
47
        "flags-implicit",
 
48
        NULL,   NULL, NULL,
 
49
        tag_flags_validate_persistent,
 
50
        tag_flags_generate
 
51
};
 
52
 
 
53
/*
 
54
 * Side effect
55
55
 */
56
56
 
57
57
static bool seff_flags_dump_context
58
58
        (const struct sieve_side_effect *seffect,
59
59
        const struct sieve_dumptime_env *denv, sieve_size_t *address);
60
60
static int seff_flags_read_context
61
 
        (const struct sieve_side_effect *seffect, 
 
61
        (const struct sieve_side_effect *seffect,
62
62
                const struct sieve_runtime_env *renv, sieve_size_t *address,
63
63
                void **context);
64
64
 
65
65
static int seff_flags_merge
66
 
        (const struct sieve_runtime_env *renv, const struct sieve_action *action, 
67
 
                const struct sieve_side_effect *old_seffect,    
 
66
        (const struct sieve_runtime_env *renv, const struct sieve_action *action,
 
67
                const struct sieve_side_effect *old_seffect,
68
68
                const struct sieve_side_effect *new_seffect, void **old_context);
69
69
 
70
70
static void seff_flags_print
71
71
        (const struct sieve_side_effect *seffect, const struct sieve_action *action,
72
72
                const struct sieve_result_print_env *rpenv, bool *keep);
73
 
static bool seff_flags_pre_execute
74
 
        (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
 
73
static int seff_flags_pre_execute
 
74
        (const struct sieve_side_effect *seffect, const struct sieve_action *action,
75
75
                const struct sieve_action_exec_env *aenv, void **context, void *tr_context);
76
76
 
77
77
const struct sieve_side_effect_def flags_side_effect = {
82
82
        seff_flags_read_context,
83
83
        seff_flags_merge,
84
84
        seff_flags_print,
85
 
        seff_flags_pre_execute, 
 
85
        seff_flags_pre_execute,
86
86
        NULL, NULL, NULL
87
87
};
88
88
 
93
93
static const struct sieve_extension_objects ext_side_effects =
94
94
        SIEVE_EXT_DEFINE_SIDE_EFFECT(flags_side_effect);
95
95
 
96
 
const struct sieve_operand_def flags_side_effect_operand = { 
97
 
        "flags operand", 
 
96
const struct sieve_operand_def flags_side_effect_operand = {
 
97
        "flags operand",
98
98
        &imap4flags_extension,
99
 
        0, 
 
99
        0,
100
100
        &sieve_side_effect_operand_class,
101
101
        &ext_side_effects
102
102
};
103
103
 
104
 
/* 
105
 
 * Tag validation 
 
104
/*
 
105
 * Tag validation
106
106
 */
107
107
 
108
108
static bool tag_flags_validate_persistent
112
112
        if ( sieve_command_find_argument(cmd, &tag_flags) == NULL ) {
113
113
                sieve_command_add_dynamic_tag(cmd, ext, &tag_flags_implicit, -1);
114
114
        }
115
 
        
 
115
 
116
116
        return TRUE;
117
117
}
118
118
 
119
119
static bool tag_flags_validate
120
 
(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
 
120
(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
121
121
        struct sieve_command *cmd)
122
122
{
123
123
        struct sieve_ast_argument *tag = *arg;
124
124
 
125
125
        /* Detach the tag itself */
126
126
        *arg = sieve_ast_argument_next(*arg);
127
 
        
 
127
 
128
128
        /* Check syntax:
129
129
         *   :flags <list-of-flags: string-list>
130
130
         */
132
132
                (valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING_LIST, FALSE) ) {
133
133
                return FALSE;
134
134
        }
135
 
        
 
135
 
136
136
        tag->parameters = *arg;
137
 
        
 
137
 
138
138
        /* Detach parameter */
139
139
        *arg = sieve_ast_arguments_detach(*arg,1);
140
140
 
141
141
        return TRUE;
142
142
}
143
143
 
144
 
/* 
145
 
 * Code generation 
 
144
/*
 
145
 * Code generation
146
146
 */
147
147
 
148
148
static bool tag_flags_generate
162
162
                /* Explicit :flags tag */
163
163
                param = arg->parameters;
164
164
 
165
 
                /* Call the generation function for the argument */ 
166
 
                if ( param->argument != NULL && param->argument->def != NULL && 
167
 
                        param->argument->def->generate != NULL && 
168
 
                        !param->argument->def->generate(cgenv, param, cmd) ) 
 
165
                /* Call the generation function for the argument */
 
166
                if ( param->argument != NULL && param->argument->def != NULL &&
 
167
                        param->argument->def->generate != NULL &&
 
168
                        !param->argument->def->generate(cgenv, param, cmd) )
169
169
                        return FALSE;
170
170
 
171
171
        } else if ( sieve_argument_is(arg, tag_flags_implicit) ) {
172
172
                /* Implicit flags */
173
173
                sieve_opr_omitted_emit(cgenv->sblock);
174
 
        
 
174
 
175
175
        } else {
176
176
                /* Something else?! */
177
177
                i_unreached();
178
178
        }
179
 
        
 
179
 
180
180
        return TRUE;
181
181
}
182
182
 
183
 
/* 
 
183
/*
184
184
 * Side effect implementation
185
185
 */
186
 
 
 
186
 
187
187
/* Context data */
188
188
 
189
189
struct seff_flags_context {
190
 
        ARRAY_DEFINE(keywords, const char *);
 
190
        ARRAY(const char *) keywords;
191
191
        enum mail_flags flags;
192
192
};
193
193
 
194
194
/* Context coding */
195
195
 
196
196
static bool seff_flags_dump_context
197
 
(const struct sieve_side_effect *seffect ATTR_UNUSED, 
 
197
(const struct sieve_side_effect *seffect ATTR_UNUSED,
198
198
        const struct sieve_dumptime_env *denv, sieve_size_t *address)
199
199
{
200
200
        return sieve_opr_stringlist_dump_ex(denv, address, "flags", "INTERNAL");
207
207
        struct seff_flags_context *ctx;
208
208
        const char *flag;
209
209
        struct ext_imap4flags_iter flit;
210
 
        
 
210
 
211
211
        ctx = p_new(pool, struct seff_flags_context, 1);
212
212
        p_array_init(&ctx->keywords, pool, 2);
213
 
        
 
213
 
214
214
        T_BEGIN {
215
 
                
 
215
 
216
216
                /* Unpack */
217
217
                ext_imap4flags_get_implicit_flags_init(&flit, this_ext, result);
218
 
                while ( (flag=ext_imap4flags_iter_get_flag(&flit)) != NULL ) {          
 
218
                while ( (flag=ext_imap4flags_iter_get_flag(&flit)) != NULL ) {
219
219
                        if (flag != NULL && *flag != '\\') {
220
220
                                /* keyword */
221
221
                                const char *keyword = p_strdup(pool, flag);
236
236
                }
237
237
 
238
238
        } T_END;
239
 
        
 
239
 
240
240
        return ctx;
241
241
}
242
242
 
243
243
static int seff_flags_do_read_context
244
 
(const struct sieve_side_effect *seffect, 
 
244
(const struct sieve_side_effect *seffect,
245
245
        const struct sieve_runtime_env *renv, sieve_size_t *address,
246
246
        void **se_context)
247
247
{
249
249
        struct seff_flags_context *ctx;
250
250
        string_t *flags_item;
251
251
        struct sieve_stringlist *flag_list = NULL;
252
 
        int ret;        
 
252
        int ret;
253
253
 
254
254
        if ( (ret=sieve_opr_stringlist_read_ex
255
255
                (renv, address, "flags", TRUE, &flag_list)) <= 0 )
256
256
                return ret;
257
 
        
 
257
 
258
258
        if ( flag_list == NULL ) {
259
 
                /* Flag list is omitted, use current value of internal 
 
259
                /* Flag list is omitted, use current value of internal
260
260
                 * variable to construct side effect context.
261
261
                 */
262
262
                *se_context = seff_flags_get_implicit_context
263
263
                        (SIEVE_OBJECT_EXTENSION(seffect), renv->result);
264
264
                return SIEVE_EXEC_OK;
265
265
        }
266
 
                
 
266
 
267
267
        ctx = p_new(pool, struct seff_flags_context, 1);
268
268
        p_array_init(&ctx->keywords, pool, 2);
269
269
 
274
274
                struct ext_imap4flags_iter flit;
275
275
 
276
276
                ext_imap4flags_iter_init(&flit, flags_item);
277
 
        
278
 
                while ( (flag=ext_imap4flags_iter_get_flag(&flit)) != NULL ) {          
 
277
 
 
278
                while ( (flag=ext_imap4flags_iter_get_flag(&flit)) != NULL ) {
279
279
                        if (flag != NULL && *flag != '\\') {
280
280
                                /* keyword */
281
281
                                const char *keyword = p_strdup(pool, flag);
298
298
                        }
299
299
                }
300
300
        }
301
 
        
 
301
 
302
302
        if ( ret < 0 )
303
303
                return flag_list->exec_status;
304
304
 
305
305
        *se_context = (void *) ctx;
306
 
        
 
306
 
307
307
        return SIEVE_EXEC_OK;
308
308
}
309
309
 
310
310
static int seff_flags_read_context
311
 
(const struct sieve_side_effect *seffect, 
 
311
(const struct sieve_side_effect *seffect,
312
312
        const struct sieve_runtime_env *renv, sieve_size_t *address,
313
313
        void **se_context)
314
314
{
324
324
/* Result verification */
325
325
 
326
326
static int seff_flags_merge
327
 
(const struct sieve_runtime_env *renv ATTR_UNUSED, 
328
 
        const struct sieve_action *action ATTR_UNUSED, 
329
 
        const struct sieve_side_effect *old_seffect ATTR_UNUSED,        
330
 
        const struct sieve_side_effect *new_seffect,    
 
327
(const struct sieve_runtime_env *renv ATTR_UNUSED,
 
328
        const struct sieve_action *action ATTR_UNUSED,
 
329
        const struct sieve_side_effect *old_seffect ATTR_UNUSED,
 
330
        const struct sieve_side_effect *new_seffect,
331
331
        void **old_context)
332
332
{
333
333
        if ( new_seffect != NULL )
334
334
                *old_context = new_seffect->context;
335
 
        
 
335
 
336
336
        return 1;
337
337
}
338
338
 
339
339
/* Result printing */
340
340
 
341
341
static void seff_flags_print
342
 
(const struct sieve_side_effect *seffect, 
343
 
        const struct sieve_action *action ATTR_UNUSED, 
 
342
(const struct sieve_side_effect *seffect,
 
343
        const struct sieve_action *action ATTR_UNUSED,
344
344
        const struct sieve_result_print_env *rpenv,bool *keep ATTR_UNUSED)
345
345
{
346
346
        struct sieve_result *result = rpenv->result;
347
 
        struct seff_flags_context *ctx = 
 
347
        struct seff_flags_context *ctx =
348
348
                (struct seff_flags_context *) seffect->context;
349
349
        unsigned int i;
350
 
        
 
350
 
351
351
        if ( ctx == NULL )
352
352
                ctx = seff_flags_get_implicit_context
353
353
                        (SIEVE_OBJECT_EXTENSION(seffect), result);
354
 
        
 
354
 
355
355
        if ( ctx->flags != 0 || array_count(&ctx->keywords) > 0 ) {
356
356
                T_BEGIN {
357
357
                        string_t *flags = t_str_new(128);
358
 
 
 
358
 
359
359
                        if ( (ctx->flags & MAIL_FLAGGED) > 0 )
360
360
                                str_printfa(flags, " \\flagged");
361
361
 
362
362
                        if ( (ctx->flags & MAIL_ANSWERED) > 0 )
363
363
                                str_printfa(flags, " \\answered");
364
 
                
 
364
 
365
365
                        if ( (ctx->flags & MAIL_DELETED) > 0 )
366
366
                                str_printfa(flags, " \\deleted");
367
 
                                        
 
367
 
368
368
                        if ( (ctx->flags & MAIL_SEEN) > 0 )
369
369
                                str_printfa(flags, " \\seen");
370
 
                        
 
370
 
371
371
                        if ( (ctx->flags & MAIL_DRAFT) > 0 )
372
372
                                str_printfa(flags, " \\draft");
373
373
 
383
383
 
384
384
/* Result execution */
385
385
 
386
 
static bool seff_flags_pre_execute
387
 
(const struct sieve_side_effect *seffect, 
 
386
static int seff_flags_pre_execute
 
387
(const struct sieve_side_effect *seffect,
388
388
        const struct sieve_action *action ATTR_UNUSED,
389
389
        const struct sieve_action_exec_env *aenv, void **context, void *tr_context)
390
 
{       
 
390
{
391
391
        struct seff_flags_context *ctx = (struct seff_flags_context *) *context;
392
392
        const char *const *keywords;
393
 
                
 
393
 
394
394
        if ( ctx == NULL ) {
395
395
                ctx = seff_flags_get_implicit_context
396
396
                        (SIEVE_OBJECT_EXTENSION(seffect), aenv->result);
397
397
                *context = (void *) ctx;
398
398
        }
399
 
                
 
399
 
400
400
        (void)array_append_space(&ctx->keywords);
401
401
        keywords = array_idx(&ctx->keywords, 0);
402
402
 
403
403
        sieve_act_store_add_flags(aenv, tr_context, keywords, ctx->flags);
404
 
        
405
 
        return TRUE;
 
404
 
 
405
        return SIEVE_EXEC_OK;
406
406
}
407
407
 
408
408