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

« back to all changes in this revision

Viewing changes to pigeonhole/src/lib-sieve/plugins/ihave/tst-ihave.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 "array.h"
 
6
 
 
7
#include "sieve-common.h"
 
8
#include "sieve-extensions.h"
 
9
#include "sieve-commands.h"
 
10
#include "sieve-validator.h"
 
11
#include "sieve-generator.h"
 
12
 
 
13
#include "ext-ihave-common.h"
 
14
 
 
15
/*
 
16
 * Ihave test
 
17
 *
 
18
 * Syntax:
 
19
 *   ihave <capabilities: string-list>
 
20
 */
 
21
 
 
22
static bool tst_ihave_validate
 
23
        (struct sieve_validator *valdtr, struct sieve_command *tst);
 
24
static bool tst_ihave_validate_const
 
25
        (struct sieve_validator *valdtr, struct sieve_command *tst,
 
26
                int *const_current, int const_next);
 
27
 
 
28
const struct sieve_command_def ihave_test = {
 
29
        "ihave",
 
30
        SCT_TEST,
 
31
        1, 0, FALSE, FALSE,
 
32
        NULL, NULL,
 
33
        tst_ihave_validate,
 
34
        tst_ihave_validate_const,
 
35
        NULL, NULL
 
36
};
 
37
 
 
38
/*
 
39
 * Code validation
 
40
 */
 
41
 
 
42
static bool tst_ihave_validate
 
43
(struct sieve_validator *valdtr, struct sieve_command *tst)
 
44
{
 
45
        struct _capability {
 
46
                const struct sieve_extension *ext;
 
47
                struct sieve_ast_argument *arg;
 
48
        };
 
49
 
 
50
        struct sieve_ast_argument *arg = tst->first_positional;
 
51
        struct sieve_ast_argument *stritem;
 
52
        ARRAY_DEFINE(capabilities, struct _capability);
 
53
        struct _capability capability;
 
54
        const struct _capability *caps;
 
55
        unsigned int i, count;
 
56
        bool all_known = TRUE;
 
57
 
 
58
        t_array_init(&capabilities, 64);
 
59
 
 
60
        tst->data = (void *) FALSE;
 
61
 
 
62
        /* Check stringlist argument */
 
63
        if ( !sieve_validate_positional_argument
 
64
                (valdtr, tst, arg, "capabilities", 1, SAAT_STRING_LIST) ) {
 
65
                return FALSE;
 
66
        }
 
67
 
 
68
        switch ( sieve_ast_argument_type(arg) ) {
 
69
        case SAAT_STRING:
 
70
                /* Single string */
 
71
                capability.arg = arg;
 
72
                capability.ext = sieve_extension_get_by_name
 
73
                        (tst->ext->svinst, sieve_ast_argument_strc(arg));
 
74
                array_append(&capabilities, &capability, 1);
 
75
 
 
76
                if ( capability.ext == NULL ) {
 
77
                        all_known = FALSE;
 
78
 
 
79
                        ext_ihave_ast_add_missing_extension
 
80
                                (tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(arg));
 
81
                }
 
82
 
 
83
                break;
 
84
 
 
85
        case SAAT_STRING_LIST:
 
86
                /* String list */
 
87
                stritem = sieve_ast_strlist_first(arg);
 
88
 
 
89
                while ( stritem != NULL ) {
 
90
                        capability.arg = stritem;
 
91
                        capability.ext = sieve_extension_get_by_name
 
92
                                (tst->ext->svinst, sieve_ast_argument_strc(stritem));
 
93
                        array_append(&capabilities, &capability, 1);
 
94
 
 
95
                        if ( capability.ext == NULL ) {
 
96
                                all_known = FALSE;
 
97
 
 
98
                                ext_ihave_ast_add_missing_extension
 
99
                                        (tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(stritem));
 
100
                        }
 
101
 
 
102
                        stritem = sieve_ast_strlist_next(stritem);
 
103
                }
 
104
 
 
105
                break;
 
106
        default:
 
107
                i_unreached();
 
108
        }
 
109
 
 
110
        if ( !all_known )
 
111
                return TRUE;
 
112
 
 
113
        /* RFC 5463, Section 4, page 4:
 
114
         *
 
115
         * The "ihave" extension is designed to be used with other extensions
 
116
         * that add tests, actions, comparators, or arguments.  Implementations
 
117
         * MUST NOT allow it to be used with extensions that change the
 
118
         * underlying Sieve grammar, or extensions like encoded-character
 
119
         * [RFC5228], or variables [RFC5229] that change how the content of
 
120
         * Sieve scripts are interpreted.  The test MUST fail and the extension
 
121
         * MUST NOT be enabled if such usage is attempted.
 
122
         *
 
123
         * FIXME: current implementation of this restriction is hardcoded and
 
124
         * therefore highly inflexible
 
125
         */
 
126
        caps = array_get(&capabilities, &count);
 
127
        for ( i = 0; i < count; i++ ) {
 
128
                if ( sieve_extension_name_is(caps[i].ext, "variables") ||
 
129
                        sieve_extension_name_is(caps[i].ext, "encoded-character") )
 
130
                        return TRUE;
 
131
        }
 
132
 
 
133
        /* Load all extensions */
 
134
        caps = array_get(&capabilities, &count);
 
135
        for ( i = 0; i < count; i++ ) {
 
136
                if ( !sieve_validator_extension_load
 
137
                        (valdtr, tst, caps[i].arg, caps[i].ext) )
 
138
                        return FALSE;
 
139
        }
 
140
 
 
141
        tst->data = (void *) TRUE;
 
142
        return TRUE;
 
143
}
 
144
 
 
145
static bool tst_ihave_validate_const
 
146
(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst,
 
147
        int *const_current, int const_next ATTR_UNUSED)
 
148
{
 
149
        if ( (bool)tst->data == TRUE )
 
150
                *const_current = 1;
 
151
        else
 
152
                *const_current = 0;
 
153
        return TRUE;
 
154
}