~ubuntu-branches/ubuntu/quantal/dovecot/quantal

« back to all changes in this revision

Viewing changes to sieve/src/lib-sieve/plugins/enotify/ext-enotify-common.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2010-06-29 09:21:32 UTC
  • mfrom: (4.1.14 sid)
  • Revision ID: james.westby@ubuntu.com-20100629092132-q4pr5lfuvmjqou19
Tags: 1:1.2.12-1ubuntu1
* Merge from Debian Unstable, remaining changes:
  + Add mail-stack-delivery as per server-maverick-mail-integration spec:
   - Update debian/rules
   - Convert existing package to a dummy package and add new binary in debian/control
   - Update maintainer scripts.
   - Move previously installed backups and config files to new package name
     space in preinst
   - Add new debian/mail-stack-delivery.prerm to handle downgrades
   - Rename debian/dovecot-postfix.* to debian/mail-stack-delivery.*
  + 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/*.
  + Add ufw integration:
    - Created debian/dovecot-common.ufw.profile.
    - debian/rules: install profile.
    - debian/control: suggest ufw.
  + debian/{control,rules}: enable PIE hardening.
  + debian/control: Update Vcs-* headers.
  + Add SMTP-AUTH support for Outlook (login auth mechanism) 
  + debian/dovecot-common.dirs: Added usr/share/doc/dovecot-common
  + debian/patches/fix-dovecot-config-parser.patch: Fix ordering of external config 
    files. (LP: #597818)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2002-2010 Dovecot Sieve authors, see the included COPYING file 
 
1
/* Copyright (c) 2002-2010 Dovecot Sieve authors, see the included COPYING file
2
2
 */
3
 
 
 
3
 
4
4
#include "lib.h"
5
5
#include "str.h"
6
6
#include "str-sanitize.h"
60
60
/*
61
61
 * Notify method registry
62
62
 */
63
 
 
 
63
 
64
64
static const struct sieve_enotify_method *ext_enotify_method_register
65
 
(struct sieve_instance *svinst, struct ext_enotify_context *ectx, 
66
 
        const struct sieve_enotify_method_def *nmth_def) 
 
65
(struct sieve_instance *svinst, struct ext_enotify_context *ectx,
 
66
        const struct sieve_enotify_method_def *nmth_def)
67
67
{
68
68
        struct sieve_enotify_method *nmth;
69
69
        int nmth_id = (int) array_count(&ectx->notify_methods);
77
77
                nmth_def->load(nmth, &nmth->context);
78
78
 
79
79
        return nmth;
80
 
 
80
}
81
81
 
82
82
void ext_enotify_methods_init
83
83
(struct sieve_instance *svinst, struct ext_enotify_context *ectx)
91
91
{
92
92
        const struct sieve_enotify_method *methods;
93
93
        unsigned int meth_count, i;
94
 
         
 
94
 
95
95
        methods = array_get(&ectx->notify_methods, &meth_count);
96
96
        for ( i = 0; i < meth_count; i++ ) {
97
97
                if ( methods[i].def != NULL && methods[i].def->unload != NULL )
102
102
}
103
103
 
104
104
const struct sieve_enotify_method *sieve_enotify_method_register
105
 
(struct sieve_instance *svinst, 
 
105
(struct sieve_instance *svinst,
106
106
        const struct sieve_enotify_method_def *nmth_def)
107
107
{
108
108
        const struct sieve_extension *ntfy_ext =
109
109
                sieve_extension_get_by_name(svinst, "enotify");
110
110
 
111
111
        if ( ntfy_ext != NULL ) {
112
 
                struct ext_enotify_context *ectx = 
 
112
                struct ext_enotify_context *ectx =
113
113
                        (struct ext_enotify_context *) ntfy_ext->context;
114
114
 
115
115
                return ext_enotify_method_register(svinst, ectx, nmth_def);
126
126
                sieve_extension_get_by_name(svinst, "enotify");
127
127
 
128
128
        if ( ntfy_ext != NULL ) {
129
 
                struct ext_enotify_context *ectx = 
 
129
                struct ext_enotify_context *ectx =
130
130
                        (struct ext_enotify_context *) ntfy_ext->context;
131
131
                int nmth_id = nmth->id;
132
132
 
133
133
                if ( nmth_id >= 0 && nmth_id < (int)array_count(&ectx->notify_methods) ) {
134
134
                        struct sieve_enotify_method *nmth_mod =
135
135
                                array_idx_modifiable(&ectx->notify_methods, nmth_id);
136
 
                        
 
136
 
137
137
                        nmth_mod->def = NULL;
138
138
                }
139
139
        }
140
140
}
141
141
 
142
142
const struct sieve_enotify_method *ext_enotify_method_find
143
 
(const struct sieve_extension *ntfy_ext, const char *identifier) 
 
143
(const struct sieve_extension *ntfy_ext, const char *identifier)
144
144
{
145
 
        struct ext_enotify_context *ectx = 
 
145
        struct ext_enotify_context *ectx =
146
146
                (struct ext_enotify_context *) ntfy_ext->context;
147
147
        unsigned int meth_count, i;
148
148
        const struct sieve_enotify_method *methods;
149
 
         
 
149
 
150
150
        methods = array_get(&ectx->notify_methods, &meth_count);
151
 
                
 
151
 
152
152
        for ( i = 0; i < meth_count; i++ ) {
153
153
                if ( methods[i].def == NULL ) continue;
154
154
 
156
156
                        return &methods[i];
157
157
                }
158
158
        }
159
 
        
 
159
 
160
160
        return NULL;
161
161
}
162
162
 
163
163
static const char *ext_notify_get_methods_string
164
164
(const struct sieve_extension *ntfy_ext)
165
165
{
166
 
        struct ext_enotify_context *ectx = 
 
166
        struct ext_enotify_context *ectx =
167
167
                (struct ext_enotify_context *) ntfy_ext->context;
168
168
        unsigned int meth_count, i;
169
169
        const struct sieve_enotify_method *methods;
170
170
        string_t *result = t_str_new(128);
171
 
         
 
171
 
172
172
        methods = array_get(&ectx->notify_methods, &meth_count);
173
 
        
 
173
 
174
174
        if ( meth_count > 0 ) {
175
175
                for ( i = 0; i < meth_count; i++ ) {
176
176
                        if ( str_len(result) > 0 )
179
179
                        if ( methods[i].def != NULL )
180
180
                                str_append(result, methods[i].def->identifier);
181
181
                }
182
 
                
 
182
 
183
183
                return str_c(result);
184
184
        }
185
 
        
 
185
 
186
186
        return NULL;
187
187
}
188
188
 
189
189
/*
190
190
 * Compile-time argument validation
191
191
 */
192
 
 
 
192
 
193
193
static const char *ext_enotify_uri_scheme_parse(const char **uri_p)
194
194
{
195
195
        string_t *scheme = t_str_new(EXT_ENOTIFY_MAX_SCHEME_LEN);
196
196
        const char *p = *uri_p;
197
197
        unsigned int len = 0;
198
 
        
 
198
 
199
199
        /* RFC 3968:
200
200
         *
201
201
         *   scheme  = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
202
202
         *
203
203
         * FIXME: we do not allow '%' in schemes. Is this correct?
204
204
         */
205
 
         
 
205
 
206
206
        if ( !i_isalpha(*p) )
207
207
                return NULL;
208
 
                
 
208
 
209
209
        str_append_c(scheme, *p);
210
210
        p++;
211
 
                
 
211
 
212
212
        while ( *p != '\0' && len < EXT_ENOTIFY_MAX_SCHEME_LEN ) {
213
 
                        
 
213
 
214
214
                if ( !i_isalnum(*p) && *p != '+' && *p != '-' && *p != '.' )
215
215
                        break;
216
 
        
 
216
 
217
217
                str_append_c(scheme, *p);
218
218
                p++;
219
219
                len++;
220
220
        }
221
 
        
 
221
 
222
222
        if ( *p != ':' )
223
223
                return NULL;
224
224
        p++;
225
 
        
 
225
 
226
226
        *uri_p = p;
227
227
        return str_c(scheme);
228
228
}
232
232
        const char **opt_name_r, const char **opt_value_r)
233
233
{
234
234
        const char *p = option;
235
 
        
 
235
 
236
236
        /* "<optionname>=<value>".
237
 
         * 
 
237
         *
238
238
         * l-d = ALPHA / DIGIT
239
239
         * l-d-p = l-d / "." / "-" / "_"
240
240
         * optionname = l-d *l-d-p
241
241
         * value = *(%x01-09 / %x0B-0C / %x0E-FF)
242
242
         */
243
 
                                
244
 
        /* 
245
 
         * Parse option name 
 
243
 
 
244
        /*
 
245
         * Parse option name
246
246
         *
247
247
         * optionname = l-d *l-d-p
248
248
         */
249
 
        
 
249
 
250
250
        /* Explicitly report empty option as such */
251
251
        if ( *p == '\0' ) {
252
252
                sieve_enotify_error(nenv, "empty option specified");
256
256
        /* l-d = ALPHA / DIGIT */
257
257
        if ( i_isalnum(*p) ) {
258
258
                p++;
259
 
        
 
259
 
260
260
                /* l-d-p = l-d / "." / "-" / "_" */
261
261
                while ( i_isalnum(*p) || *p == '.' || *p == '-' || *p == '_' )
262
262
                        p++;
263
263
        }
264
 
        
 
264
 
265
265
        /* Parsing must end at '=' and we must parse at least one character */
266
266
        if ( *p != '=' || p == option ) {
267
267
                sieve_enotify_error(nenv, "invalid option name specified in option '%s'",
268
268
                                str_sanitize(option, 80));
269
269
                return FALSE;
270
270
        }
271
 
        
 
271
 
272
272
        /* Assign option name */
273
 
        if ( opt_name_r != NULL ) 
 
273
        if ( opt_name_r != NULL )
274
274
                *opt_name_r = t_strdup_until(option, p);
275
 
        
 
275
 
276
276
        /* Skip '=' */
277
277
        p++;
278
 
        
 
278
 
279
279
        /* Exit now if only the option name is of interest */
280
280
        if ( name_only )
281
281
                return TRUE;
282
 
                        
283
 
        /* 
 
282
 
 
283
        /*
284
284
         * Parse option value
285
285
         */
286
 
         
 
286
 
287
287
        /* value = *(%x01-09 / %x0B-0C / %x0E-FF) */
288
288
        while ( *p != '\0' && *p != 0x0A && *p != 0x0D )
289
289
                p++;
290
 
                
 
290
 
291
291
        /* Parse must end at end of string */
292
292
        if ( *p != '\0' ) {
293
 
                sieve_enotify_error(nenv, 
 
293
                sieve_enotify_error(nenv,
294
294
                        "notify command: invalid option value specified in option '%s'",
295
295
                                str_sanitize(option, 80));
296
296
                return FALSE;
297
297
        }
298
 
        
 
298
 
299
299
        /* Assign option value */
300
300
        if ( opt_value_r != NULL )
301
301
                *opt_value_r = p;
302
 
                
 
302
 
303
303
        return TRUE;
304
 
 
304
}
305
305
 
306
306
struct _ext_enotify_option_check_context {
307
307
        struct sieve_validator *valdtr;
311
311
static int _ext_enotify_option_check
312
312
(void *context, struct sieve_ast_argument *arg)
313
313
{
314
 
        struct _ext_enotify_option_check_context *optn_context = 
 
314
        struct _ext_enotify_option_check_context *optn_context =
315
315
                (struct _ext_enotify_option_check_context *) context;
316
316
        struct sieve_validator *valdtr = optn_context->valdtr;
317
317
        const struct sieve_enotify_method *method = optn_context->method;
319
319
        const char *option = sieve_ast_argument_strc(arg);
320
320
        const char *opt_name = NULL, *opt_value = NULL;
321
321
        bool result = TRUE, check = TRUE;
322
 
        
 
322
 
323
323
        /* Compose log structure */
324
324
        memset(&nenv, 0, sizeof(nenv));
325
 
        nenv.method = method;   
 
325
        nenv.method = method;
326
326
        nenv.ehandler = sieve_prefix_ehandler_create
327
 
                (sieve_validator_error_handler(valdtr), 
 
327
                (sieve_validator_error_handler(valdtr),
328
328
                        sieve_error_script_location
329
 
                                (sieve_validator_script(valdtr), arg->source_line), 
 
329
                                (sieve_validator_script(valdtr), arg->source_line),
330
330
                        "notify command");
331
 
                
 
331
 
332
332
        /* Parse option */
333
333
        if ( !sieve_argument_is_string_literal(arg) ) {
334
334
                /* Variable string: partial option parse
335
 
                 * 
 
335
                 *
336
336
                 * If the string item is not a string literal, it cannot be validated fully
337
337
                 * at compile time. We can however check whether the '=' is in the string
338
338
                 * specification and whether the part before the '=' is a valid option name.
339
339
                 * In that case, the method option check function is called with the value
340
340
                 * parameter equal to NULL, meaning that it should only check the validity
341
341
                 * of the option itself and not the assigned value.
342
 
                 */ 
 
342
                 */
343
343
                if ( !ext_enotify_option_parse(NULL, option, TRUE, &opt_name, &opt_value) )
344
344
                        check = FALSE;
345
345
        } else {
348
348
                        (&nenv, option, FALSE, &opt_name, &opt_value) )
349
349
                        result = FALSE;
350
350
        }
351
 
        
 
351
 
352
352
        /* Call method's option check function */
353
 
        if ( result && check && method->def != NULL && 
354
 
                method->def->compile_check_option != NULL ) 
355
 
                result = method->def->compile_check_option(&nenv, opt_name, opt_value); 
356
 
        
 
353
        if ( result && check && method->def != NULL &&
 
354
                method->def->compile_check_option != NULL )
 
355
                result = method->def->compile_check_option(&nenv, opt_name, opt_value);
 
356
 
357
357
        sieve_error_handler_unref(&nenv.ehandler);
358
358
 
359
359
        return result;
361
361
 
362
362
bool ext_enotify_compile_check_arguments
363
363
(struct sieve_validator *valdtr, struct sieve_command *cmd,
364
 
        struct sieve_ast_argument *uri_arg, struct sieve_ast_argument *msg_arg, 
 
364
        struct sieve_ast_argument *uri_arg, struct sieve_ast_argument *msg_arg,
365
365
        struct sieve_ast_argument *from_arg, struct sieve_ast_argument *options_arg)
366
366
{
367
367
        const struct sieve_extension *this_ext = cmd->ext;
376
376
         */
377
377
        if ( !sieve_argument_is_string_literal(uri_arg) )
378
378
                return TRUE;
379
 
        
 
379
 
380
380
        /* Parse scheme part of URI */
381
381
        if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL ) {
382
 
                sieve_argument_validate_error(valdtr, uri_arg, 
383
 
                        "notify command: invalid scheme part for method URI '%s'", 
 
382
                sieve_argument_validate_error(valdtr, uri_arg,
 
383
                        "notify command: invalid scheme part for method URI '%s'",
384
384
                        str_sanitize(sieve_ast_argument_strc(uri_arg), 80));
385
385
                return FALSE;
386
386
        }
387
 
        
 
387
 
388
388
        /* Find used method with the parsed scheme identifier */
389
389
        if ( (method=ext_enotify_method_find(this_ext, scheme)) == NULL ) {
390
 
                sieve_argument_validate_error(valdtr, uri_arg, 
 
390
                sieve_argument_validate_error(valdtr, uri_arg,
391
391
                        "notify command: invalid method '%s'", scheme);
392
392
                return FALSE;
393
393
        }
396
396
 
397
397
        /* Compose log structure */
398
398
        memset(&nenv, 0, sizeof(nenv));
399
 
        nenv.method = method;   
400
 
        
 
399
        nenv.method = method;
 
400
 
401
401
        /* Check URI itself */
402
402
        if ( result && method->def->compile_check_uri != NULL ) {
403
403
                /* Set log location to location of URI argument */
404
404
                nenv.ehandler = sieve_prefix_ehandler_create
405
 
                (sieve_validator_error_handler(valdtr), 
 
405
                (sieve_validator_error_handler(valdtr),
406
406
                        sieve_error_script_location
407
 
                                (sieve_validator_script(valdtr), uri_arg->source_line), 
 
407
                                (sieve_validator_script(valdtr), uri_arg->source_line),
408
408
                        "notify command");
409
409
 
410
410
                /* Execute method check function */
418
418
                /* Set log location to location of :message argument */
419
419
                sieve_error_handler_unref(&nenv.ehandler);
420
420
                nenv.ehandler = sieve_prefix_ehandler_create
421
 
                (sieve_validator_error_handler(valdtr), 
 
421
                (sieve_validator_error_handler(valdtr),
422
422
                        sieve_error_script_location
423
 
                                (sieve_validator_script(valdtr), msg_arg->source_line), 
 
423
                                (sieve_validator_script(valdtr), msg_arg->source_line),
424
424
                        "notify command");
425
425
 
426
426
                /* Execute method check function */
434
434
                /* Set log location to location of :from argument */
435
435
                sieve_error_handler_unref(&nenv.ehandler);
436
436
                nenv.ehandler = sieve_prefix_ehandler_create
437
 
                (sieve_validator_error_handler(valdtr), 
 
437
                (sieve_validator_error_handler(valdtr),
438
438
                        sieve_error_script_location
439
 
                                (sieve_validator_script(valdtr), from_arg->source_line), 
 
439
                                (sieve_validator_script(valdtr), from_arg->source_line),
440
440
                                "notify command");
441
441
 
442
442
                /* Execute method check function */
445
445
        }
446
446
 
447
447
        sieve_error_handler_unref(&nenv.ehandler);
448
 
        
 
448
 
449
449
        /* Check :options argument */
450
450
        if ( result && options_arg != NULL ) {
451
451
                struct sieve_ast_argument *option = options_arg;
452
452
                struct _ext_enotify_option_check_context optn_context = { valdtr, method };
453
 
                
 
453
 
454
454
                /* Parse and check options */
455
455
                result = ( sieve_ast_stringlist_map
456
456
                        (&option, (void *) &optn_context, _ext_enotify_option_check) > 0 );
457
 
                        
 
457
 
458
458
                /* Discard argument if options are not accepted by method */
459
459
                if ( result && method->def->compile_check_option == NULL ) {
460
 
                        sieve_argument_validate_warning(valdtr, options_arg, 
 
460
                        sieve_argument_validate_warning(valdtr, options_arg,
461
461
                                "notify command: method '%s' accepts no options", scheme);
462
462
                        (void)sieve_ast_arguments_detach(options_arg,1);
463
463
                }
464
464
        }
465
 
        
 
465
 
466
466
        return result;
467
467
}
468
468
 
469
469
/*
470
470
 * Runtime operand checking
471
471
 */
472
 
 
 
472
 
473
473
bool ext_enotify_runtime_method_validate
474
474
(const struct sieve_runtime_env *renv, unsigned int source_line,
475
475
        string_t *method_uri)
479
479
        const char *uri = str_c(method_uri);
480
480
        const char *scheme;
481
481
        bool result = TRUE;
482
 
        
 
482
 
483
483
        /* Get the method */
484
 
        
 
484
 
485
485
        if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL )
486
486
                return FALSE;
487
 
        
 
487
 
488
488
        if ( (method=ext_enotify_method_find(this_ext, scheme)) == NULL )
489
489
                return FALSE;
490
 
                
 
490
 
491
491
        /* Validate the provided URI */
492
 
        
 
492
 
493
493
        if ( method->def != NULL && method->def->runtime_check_uri != NULL ) {
494
 
                struct sieve_enotify_env nenv; 
495
 
                
 
494
                struct sieve_enotify_env nenv;
 
495
 
496
496
                memset(&nenv, 0, sizeof(nenv));
497
497
                nenv.method = method;
498
498
                nenv.ehandler = sieve_prefix_ehandler_create
499
 
                        (sieve_interpreter_get_error_handler(renv->interp), 
500
 
                                sieve_error_script_location(renv->script, source_line), 
 
499
                        (sieve_interpreter_get_error_handler(renv->interp),
 
500
                                sieve_error_script_location(renv->script, source_line),
501
501
                                "valid_notify_method test");
502
502
 
503
503
                /* Use the method check function to validate the URI */
508
508
 
509
509
        return result;
510
510
}
511
 
 
 
511
 
512
512
static const struct sieve_enotify_method *ext_enotify_get_method
513
513
(const struct sieve_runtime_env *renv, unsigned int source_line,
514
514
        string_t *method_uri, const char **uri_body_r)
517
517
        const struct sieve_enotify_method *method;
518
518
        const char *uri = str_c(method_uri);
519
519
        const char *scheme;
520
 
        
 
520
 
521
521
        /* Parse part before ':' of the uri (the scheme) and use it to identify
522
522
         * notify method.
523
523
         */
524
524
        if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL ) {
525
525
                sieve_runtime_error
526
526
                        (renv, sieve_error_script_location(renv->script, source_line),
527
 
                                "invalid scheme part for method URI '%s'", 
 
527
                                "invalid scheme part for method URI '%s'",
528
528
                                str_sanitize(str_c(method_uri), 80));
529
529
                return NULL;
530
530
        }
531
 
        
 
531
 
532
532
        /* Find the notify method */
533
533
        if ( (method=ext_enotify_method_find(this_ext, scheme)) == NULL ) {
534
534
                sieve_runtime_error
549
549
        const struct sieve_enotify_method *method;
550
550
        const char *uri_body;
551
551
        const char *result = NULL;
552
 
        
 
552
 
553
553
        /* Get method */
554
554
        method = ext_enotify_get_method(renv, source_line, method_uri, &uri_body);
555
555
        if ( method == NULL ) return NULL;
556
 
        
 
556
 
557
557
        /* Get requested capability */
558
 
        if ( method->def != NULL && 
 
558
        if ( method->def != NULL &&
559
559
                method->def->runtime_get_method_capability != NULL ) {
560
 
                struct sieve_enotify_env nenv; 
 
560
                struct sieve_enotify_env nenv;
561
561
 
562
562
                memset(&nenv, 0, sizeof(nenv));
563
563
                nenv.method = method;
564
564
                nenv.ehandler = sieve_prefix_ehandler_create
565
 
                        (sieve_interpreter_get_error_handler(renv->interp), 
566
 
                                sieve_error_script_location(renv->script, source_line), 
 
565
                        (sieve_interpreter_get_error_handler(renv->interp),
 
566
                                sieve_error_script_location(renv->script, source_line),
567
567
                                "notify_method_capability test");
568
 
                
 
568
 
569
569
                /* Execute method function to acquire capability value */
570
570
                result = method->def->runtime_get_method_capability
571
571
                        (&nenv, str_c(method_uri), uri_body, capability);
578
578
 
579
579
int ext_enotify_runtime_check_operands
580
580
(const struct sieve_runtime_env *renv, unsigned int source_line,
581
 
        string_t *method_uri, string_t *message, string_t *from, 
582
 
        struct sieve_coded_stringlist *options, 
 
581
        string_t *method_uri, string_t *message, string_t *from,
 
582
        struct sieve_coded_stringlist *options,
583
583
        const struct sieve_enotify_method **method_r, void **method_context)
584
584
{
585
585
        const struct sieve_enotify_method *method;
586
586
        const char *uri_body;
587
 
        
 
587
 
588
588
        /* Get method */
589
589
        method = ext_enotify_get_method(renv, source_line, method_uri, &uri_body);
590
590
        if ( method == NULL ) return SIEVE_EXEC_FAILURE;
591
 
        
 
591
 
592
592
        /* Check provided operands */
593
593
        if ( method->def != NULL && method->def->runtime_check_operands != NULL ) {
594
 
                struct sieve_enotify_env nenv; 
 
594
                struct sieve_enotify_env nenv;
595
595
                int ret = SIEVE_EXEC_OK;
596
596
 
597
597
                memset(&nenv, 0, sizeof(nenv));
598
598
                nenv.method = method;
599
599
                nenv.ehandler = sieve_prefix_ehandler_create
600
 
                        (sieve_interpreter_get_error_handler(renv->interp), 
601
 
                                sieve_error_script_location(renv->script, source_line), 
 
600
                        (sieve_interpreter_get_error_handler(renv->interp),
 
601
                                sieve_error_script_location(renv->script, source_line),
602
602
                                "notify action");
603
603
 
604
604
                /* Execute check function */
605
605
                if ( method->def->runtime_check_operands
606
 
                        (&nenv, str_c(method_uri), uri_body, message, from, 
 
606
                        (&nenv, str_c(method_uri), uri_body, message, from,
607
607
                                sieve_result_pool(renv->result), method_context) ) {
608
 
                        
 
608
 
609
609
                        /* Check any provided options */
610
 
                        if ( options != NULL ) {                        
 
610
                        if ( options != NULL ) {
611
611
                                int result = TRUE;
612
612
                                string_t *option = NULL;
613
 
                        
 
613
 
614
614
                                /* Iterate through all provided options */
615
 
                                while ( result && 
616
 
                                        (result=sieve_coded_stringlist_next_item(options, &option)) && 
 
615
                                while ( result &&
 
616
                                        (result=sieve_coded_stringlist_next_item(options, &option)) &&
617
617
                                        option != NULL ) {
618
618
                                        const char *opt_name = NULL, *opt_value = NULL;
619
 
                                
 
619
 
620
620
                                        /* Parse option into <optionname> and <value> */
621
621
                                        if ( ext_enotify_option_parse
622
622
                                                (&nenv, str_c(option), FALSE, &opt_name, &opt_value) ) {
623
 
                                        
 
623
 
624
624
                                                /* Set option */
625
625
                                                if ( method->def->runtime_set_option != NULL ) {
626
626
                                                        (void) method->def->runtime_set_option
628
628
                                                }
629
629
                                        }
630
630
                                }
631
 
                        
 
631
 
632
632
                                /* Check for binary corruptions encountered during string list iteration
633
633
                                 */
634
634
                                if ( result ) {
641
641
                                }
642
642
 
643
643
                        } else {
644
 
                                /* No options */                        
 
644
                                /* No options */
645
645
                                *method_r = method;
646
646
                        }
647
647
 
648
 
                } else {        
 
648
                } else {
649
649
                        /* Operand check failed */
650
650
                        ret = SIEVE_EXEC_FAILURE;
651
651
                }
655
655
        }
656
656
 
657
657
        /* No check function defined: a most unlikely situation */
658
 
        *method_context = NULL; 
 
658
        *method_context = NULL;
659
659
        *method_r = method;
660
660
        return SIEVE_EXEC_OK;
661
661
}
668
668
(const struct sieve_enotify_print_env *penv, const char *fmt, ...)
669
669
{
670
670
        va_list args;
671
 
        
672
 
        va_start(args, fmt);    
 
671
 
 
672
        va_start(args, fmt);
673
673
        sieve_result_vprintf(penv->result_penv, fmt, args);
674
 
        va_end(args);    
 
674
        va_end(args);
675
675
}
676
676