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

« back to all changes in this revision

Viewing changes to sieve/src/lib-sieve/cmd-if.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short, Scott Kitterman
  • Date: 2010-06-22 10:33:51 UTC
  • mfrom: (1.13.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100622103351-ifbmnklp8kxrhb30
Tags: 1:1.2.12-0ubuntu1
* New upstream release:
  - deliver: Don't crash when a message with Auto-submitted: header gets
   rejected.
  - lib-storage: Fixed header searches to work correctly when there are
    multiple headers with same name.
  - dict client: Disconnect from dict server after 1 second of idling.
  - dict: If process crashed, it wasn't automatically restarted
  - dict file: If dict file's group permissions equal world permissions,
    don't try to change its gid.
  - maildir: Fixed a memory leak when copying with hardlinks.
  - maildir: Expunging last messages may have assert-crashed if their
    filenames had just changed.
 * Update sieve patch to 0.1.17
 * debian/dovecot-common.postinst: Add warning about expired certificate.
   (Debian Bug: #576455)
 * Silence lintian warnings.

 [Scott Kitterman]
 * Rename dovecot-postfix to mail-stack-delivery 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.*

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 
15
15
/* If command
16
16
 *
17
 
 * Syntax:
 
17
 * Syntax:   
18
18
 *   if <test1: test> <block1: block>
19
19
 */
20
20
 
23
23
static bool cmd_if_generate
24
24
        (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd);
25
25
 
26
 
const struct sieve_command_def cmd_if = {
27
 
        "if",
28
 
        SCT_COMMAND,
 
26
const struct sieve_command_def cmd_if = { 
 
27
        "if", 
 
28
        SCT_COMMAND, 
29
29
        0, 1, TRUE, TRUE,
30
30
        NULL, NULL,
31
 
        cmd_if_validate,
32
 
        cmd_if_generate,
33
 
        NULL
 
31
        cmd_if_validate, 
 
32
        cmd_if_generate, 
 
33
        NULL 
34
34
};
35
35
 
36
36
/* ElsIf command
43
43
        (struct sieve_validator *valdtr, struct sieve_command *cmd);
44
44
 
45
45
const struct sieve_command_def cmd_elsif = {
46
 
    "elsif",
 
46
    "elsif", 
47
47
        SCT_COMMAND,
48
 
        0, 1, TRUE, TRUE,
49
 
        NULL, NULL,
50
 
        cmd_elsif_validate,
51
 
        cmd_if_generate,
52
 
        NULL
 
48
        0, 1, TRUE, TRUE, 
 
49
        NULL, NULL, 
 
50
        cmd_elsif_validate, 
 
51
        cmd_if_generate, 
 
52
        NULL 
53
53
};
54
54
 
55
 
/* Else command
 
55
/* Else command 
56
56
 *
57
 
 * Syntax:
 
57
 * Syntax:   
58
58
 *   else <block>
59
59
 */
60
60
 
62
62
        (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd);
63
63
 
64
64
const struct sieve_command_def cmd_else = {
65
 
    "else",
66
 
        SCT_COMMAND,
 
65
    "else", 
 
66
        SCT_COMMAND, 
67
67
        0, 0, TRUE, TRUE,
68
68
        NULL, NULL,
69
 
        cmd_elsif_validate,
70
 
        cmd_else_generate,
71
 
        NULL
 
69
        cmd_elsif_validate, 
 
70
        cmd_else_generate, 
 
71
        NULL 
72
72
};
73
73
 
74
 
/*
 
74
/* 
75
75
 * Context management
76
76
 */
77
77
 
78
78
struct cmd_if_context_data {
79
79
        struct cmd_if_context_data *previous;
80
80
        struct cmd_if_context_data *next;
81
 
 
 
81
        
82
82
        bool jump_generated;
83
83
        sieve_size_t exit_jump;
84
84
};
85
85
 
86
86
static void cmd_if_initialize_context_data
87
 
(struct sieve_command *cmd, struct cmd_if_context_data *previous)
88
 
{
 
87
(struct sieve_command *cmd, struct cmd_if_context_data *previous) 
 
88
{       
89
89
        struct cmd_if_context_data *cmd_data;
90
90
 
91
91
        /* Assign context */
95
95
 
96
96
        /* Update linked list of contexts */
97
97
        cmd_data->previous = previous;
98
 
        cmd_data->next = NULL;
 
98
        cmd_data->next = NULL;  
99
99
        if ( previous != NULL )
100
100
                previous->next = cmd_data;
101
 
 
 
101
        
102
102
        /* Assign to command context */
103
103
        cmd->data = cmd_data;
104
104
}
105
105
 
106
 
/*
107
 
 * Validation
 
106
/* 
 
107
 * Validation 
108
108
 */
109
109
 
110
110
static bool cmd_if_validate
111
 
(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd)
112
 
{
 
111
(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) 
 
112
113
113
        /* Start if-command structure */
114
114
        cmd_if_initialize_context_data(cmd, NULL);
115
 
 
 
115
        
116
116
        return TRUE;
117
117
}
118
118
 
123
123
 
124
124
        /* Check valid command placement */
125
125
        if ( prev == NULL ||
126
 
                ( !sieve_command_is(prev, cmd_if) && !sieve_command_is(prev, cmd_elsif) ) )
127
 
        {
128
 
                sieve_command_validate_error(valdtr, cmd,
129
 
                        "the %s command must follow an if or elseif command",
 
126
                ( !sieve_command_is(prev, cmd_if) && !sieve_command_is(prev, cmd_elsif) ) ) 
 
127
        {               
 
128
                sieve_command_validate_error(valdtr, cmd, 
 
129
                        "the %s command must follow an if or elseif command", 
130
130
                        sieve_command_identifier(cmd));
131
131
                return FALSE;
132
132
        }
133
 
 
134
 
        /* Previous command in this block is 'if' or 'elsif', so we can safely refer
135
 
         * to its context data
 
133
        
 
134
        /* Previous command in this block is 'if' or 'elsif', so we can safely refer 
 
135
         * to its context data 
136
136
         */
137
137
        cmd_if_initialize_context_data(cmd, prev->data);
138
138
 
139
139
        return TRUE;
140
140
}
141
141
 
142
 
/*
143
 
 * Code generation
 
142
/* 
 
143
 * Code generation 
144
144
 */
145
145
 
146
146
/* The if command does not generate specific IF-ELSIF-ELSE opcodes, but only uses
147
 
 * JMP instructions. This is why the implementation of the if command does not
 
147
 * JMP instructions. This is why the implementation of the if command does not 
148
148
 * include an opcode implementation.
149
149
 */
150
150
 
151
151
static void cmd_if_resolve_exit_jumps
152
 
(struct sieve_binary *sbin, struct cmd_if_context_data *cmd_data)
 
152
(struct sieve_binary *sbin, struct cmd_if_context_data *cmd_data) 
153
153
{
154
154
        struct cmd_if_context_data *if_ctx = cmd_data->previous;
155
 
 
156
 
        /* Iterate backwards through all if-command contexts and resolve the
 
155
        
 
156
        /* Iterate backwards through all if-command contexts and resolve the 
157
157
         * exit jumps to the current code position.
158
158
         */
159
159
        while ( if_ctx != NULL ) {
160
 
                if ( if_ctx->jump_generated )
 
160
                if ( if_ctx->jump_generated ) 
161
161
                        sieve_binary_resolve_offset(sbin, if_ctx->exit_jump);
162
 
                if_ctx = if_ctx->previous;
 
162
                if_ctx = if_ctx->previous;      
163
163
        }
164
164
}
165
165
 
167
167
(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd)
168
168
{
169
169
        struct sieve_binary *sbin = cgenv->sbin;
170
 
        struct cmd_if_context_data *cmd_data =
 
170
        struct cmd_if_context_data *cmd_data = 
171
171
                (struct cmd_if_context_data *) cmd->data;
172
172
        struct sieve_ast_node *test;
173
173
        struct sieve_jumplist jmplist;
174
 
 
 
174
        
175
175
        /* Prepare jumplist */
176
176
        sieve_jumplist_init_temp(&jmplist, sbin);
177
 
 
 
177
        
178
178
        /* Generate test condition */
179
179
        test = sieve_ast_test_first(cmd->ast_node);
180
180
        if ( !sieve_generate_test(cgenv, test, &jmplist, FALSE) )
181
181
                return FALSE;
182
 
 
 
182
                
183
183
        /* Case true { */
184
 
        if ( !sieve_generate_block(cgenv, cmd->ast_node) )
 
184
        if ( !sieve_generate_block(cgenv, cmd->ast_node) ) 
185
185
                return FALSE;
186
 
 
 
186
        
187
187
        /* Are we the final command in this if-elsif-else structure? */
188
188
        if ( cmd_data->next != NULL ) {
189
 
                /* No, generate jump to end of if-elsif-else structure (resolved later)
190
 
                 * This of course is not necessary if the {} block contains a command
 
189
                /* No, generate jump to end of if-elsif-else structure (resolved later) 
 
190
                 * This of course is not necessary if the {} block contains a command 
191
191
                 * like stop at top level that unconditionally exits the block already
192
 
                 * anyway.
 
192
                 * anyway. 
193
193
                 */
194
194
                if ( !sieve_command_block_exits_unconditionally(cmd) ) {
195
195
                        sieve_operation_emit(sbin, NULL, &sieve_jmp_operation);
200
200
                /* Yes, Resolve previous exit jumps to this point */
201
201
                cmd_if_resolve_exit_jumps(sbin, cmd_data);
202
202
        }
203
 
 
 
203
        
204
204
        /* Case false ... (subsequent elsif/else commands might generate more) */
205
 
        sieve_jumplist_resolve(&jmplist);
206
 
 
 
205
        sieve_jumplist_resolve(&jmplist);       
 
206
                
207
207
        return TRUE;
208
208
}
209
209
 
212
212
{
213
213
        struct cmd_if_context_data *cmd_data =
214
214
                (struct cmd_if_context_data *) cmd->data;
215
 
 
 
215
        
216
216
        /* Else { */
217
 
        if ( !sieve_generate_block(cgenv, cmd->ast_node) )
 
217
        if ( !sieve_generate_block(cgenv, cmd->ast_node) ) 
218
218
                return FALSE;
219
 
 
220
 
        /* } End: resolve all exit blocks */
 
219
                
 
220
        /* } End: resolve all exit blocks */    
221
221
        cmd_if_resolve_exit_jumps(cgenv->sbin, cmd_data);
222
 
 
 
222
                
223
223
        return TRUE;
224
224
}
225
225