/src/pigeonhole/src/lib-sieve/plugins/copy/ext-copy.c
Line | Count | Source |
1 | | /* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file |
2 | | */ |
3 | | |
4 | | /* Extension copy |
5 | | * -------------- |
6 | | * |
7 | | * Authors: Stephan Bosch |
8 | | * Specification: RFC 3894 |
9 | | * Implementation: full |
10 | | * Status: testing |
11 | | * |
12 | | */ |
13 | | |
14 | | #include "sieve-common.h" |
15 | | |
16 | | #include "sieve-code.h" |
17 | | #include "sieve-extensions.h" |
18 | | #include "sieve-actions.h" |
19 | | #include "sieve-commands.h" |
20 | | #include "sieve-validator.h" |
21 | | #include "sieve-generator.h" |
22 | | #include "sieve-interpreter.h" |
23 | | #include "sieve-result.h" |
24 | | |
25 | | #include "sieve-ext-copy.h" |
26 | | |
27 | | /* |
28 | | * Forward declarations |
29 | | */ |
30 | | |
31 | | static const struct sieve_argument_def copy_tag; |
32 | | static const struct sieve_operand_def copy_side_effect_operand; |
33 | | |
34 | | /* |
35 | | * Extension |
36 | | */ |
37 | | |
38 | | static bool |
39 | | ext_copy_validator_load(const struct sieve_extension *ext, |
40 | | struct sieve_validator *valdtr); |
41 | | |
42 | | const struct sieve_extension_def copy_extension = { |
43 | | .name = "copy", |
44 | | .validator_load = ext_copy_validator_load, |
45 | | SIEVE_EXT_DEFINE_OPERAND(copy_side_effect_operand), |
46 | | }; |
47 | | |
48 | | static bool |
49 | | ext_copy_validator_load(const struct sieve_extension *ext, |
50 | | struct sieve_validator *valdtr) |
51 | 0 | { |
52 | | /* Register copy tag with redirect and fileinto commands and we don't |
53 | | care whether these commands are registered or even whether they will |
54 | | be registered at all. The validator handles either situation |
55 | | gracefully. |
56 | | */ |
57 | 0 | sieve_validator_register_external_tag(valdtr, "redirect", ext, |
58 | 0 | ©_tag, SIEVE_OPT_SIDE_EFFECT); |
59 | 0 | sieve_validator_register_external_tag(valdtr, "fileinto", ext, |
60 | 0 | ©_tag, SIEVE_OPT_SIDE_EFFECT); |
61 | 0 | return TRUE; |
62 | 0 | } |
63 | | |
64 | | /* |
65 | | * Side effect |
66 | | */ |
67 | | |
68 | | static void |
69 | | seff_copy_print(const struct sieve_side_effect *seffect, |
70 | | const struct sieve_action *action, |
71 | | const struct sieve_result_print_env *rpenv, bool *keep); |
72 | | static int |
73 | | seff_copy_post_execute(const struct sieve_side_effect *seffect ATTR_UNUSED, |
74 | | const struct sieve_action_exec_env *aenv ATTR_UNUSED, |
75 | | void *tr_context ATTR_UNUSED, |
76 | | void *se_tr_context ATTR_UNUSED, bool *keep); |
77 | | |
78 | | const struct sieve_side_effect_def copy_side_effect = { |
79 | | SIEVE_OBJECT("copy", ©_side_effect_operand, 0), |
80 | | .to_action = &act_store, |
81 | | .print = seff_copy_print, |
82 | | .post_execute = seff_copy_post_execute, |
83 | | }; |
84 | | |
85 | | /* |
86 | | * Tagged argument |
87 | | */ |
88 | | |
89 | | static bool |
90 | | tag_copy_validate(struct sieve_validator *valdtr, |
91 | | struct sieve_ast_argument **arg, struct sieve_command *cmd); |
92 | | static bool |
93 | | tag_copy_generate(const struct sieve_codegen_env *cgenv, |
94 | | struct sieve_ast_argument *arg, struct sieve_command *cmd); |
95 | | |
96 | | static const struct sieve_argument_def copy_tag = { |
97 | | .identifier = "copy", |
98 | | .validate = tag_copy_validate, |
99 | | .generate = tag_copy_generate, |
100 | | }; |
101 | | |
102 | | /* |
103 | | * Operand |
104 | | */ |
105 | | |
106 | | static const struct sieve_extension_objects ext_side_effects = |
107 | | SIEVE_EXT_DEFINE_SIDE_EFFECT(copy_side_effect); |
108 | | |
109 | | static const struct sieve_operand_def copy_side_effect_operand = { |
110 | | .name = "copy operand", |
111 | | .ext_def = ©_extension, |
112 | | .class = &sieve_side_effect_operand_class, |
113 | | .interface = &ext_side_effects, |
114 | | }; |
115 | | |
116 | | /* |
117 | | * Tag registration |
118 | | */ |
119 | | |
120 | | void sieve_ext_copy_register_tag(struct sieve_validator *valdtr, |
121 | | const struct sieve_extension *copy_ext, |
122 | | const char *command) |
123 | 0 | { |
124 | 0 | if (sieve_validator_extension_loaded(valdtr, copy_ext)) { |
125 | 0 | sieve_validator_register_external_tag( |
126 | 0 | valdtr, command, copy_ext, ©_tag, |
127 | 0 | SIEVE_OPT_SIDE_EFFECT); |
128 | 0 | } |
129 | 0 | } |
130 | | |
131 | | /* |
132 | | * Tag validation |
133 | | */ |
134 | | |
135 | | static bool |
136 | | tag_copy_validate(struct sieve_validator *valdtr ATTR_UNUSED, |
137 | | struct sieve_ast_argument **arg ATTR_UNUSED, |
138 | | struct sieve_command *cmd ATTR_UNUSED) |
139 | 0 | { |
140 | 0 | *arg = sieve_ast_argument_next(*arg); |
141 | |
|
142 | 0 | return TRUE; |
143 | 0 | } |
144 | | |
145 | | /* |
146 | | * Code generation |
147 | | */ |
148 | | |
149 | | static bool |
150 | | tag_copy_generate(const struct sieve_codegen_env *cgenv, |
151 | | struct sieve_ast_argument *arg, |
152 | | struct sieve_command *cmd ATTR_UNUSED) |
153 | 0 | { |
154 | 0 | if (sieve_ast_argument_type(arg) != SAAT_TAG) |
155 | 0 | return FALSE; |
156 | | |
157 | 0 | sieve_opr_side_effect_emit(cgenv->sblock, sieve_argument_ext(arg), |
158 | 0 | ©_side_effect); |
159 | 0 | return TRUE; |
160 | 0 | } |
161 | | |
162 | | /* |
163 | | * Side effect implementation |
164 | | */ |
165 | | |
166 | | static void |
167 | | seff_copy_print(const struct sieve_side_effect *seffect ATTR_UNUSED, |
168 | | const struct sieve_action *action ATTR_UNUSED, |
169 | | const struct sieve_result_print_env *rpenv, bool *keep) |
170 | 0 | { |
171 | 0 | sieve_result_seffect_printf(rpenv, "preserve implicit keep"); |
172 | 0 | *keep = TRUE; |
173 | 0 | } |
174 | | |
175 | | static int |
176 | | seff_copy_post_execute(const struct sieve_side_effect *seffect ATTR_UNUSED, |
177 | | const struct sieve_action_exec_env *aenv ATTR_UNUSED, |
178 | | void *tr_context ATTR_UNUSED, |
179 | | void *se_tr_context ATTR_UNUSED, bool *keep) |
180 | 0 | { |
181 | 0 | *keep = TRUE; |
182 | 0 | return SIEVE_EXEC_OK; |
183 | 0 | } |