1 #ifndef SIEVE_BINARY_H
2 #define SIEVE_BINARY_H
3
4 #include "lib.h"
5
6 #include "sieve-common.h"
7
8 /*
9 * Config
10 */
11
12 #define SIEVE_BINARY_VERSION_MAJOR 2
13 #define SIEVE_BINARY_VERSION_MINOR 0
14
15 #define SIEVE_BINARY_BASE_HEADER_SIZE 20
16
17 /*
18 * Binary object
19 */
20
21 struct sieve_binary;
22
23 struct sieve_binary *sieve_binary_create_new(struct sieve_script *script);
24 void sieve_binary_ref(struct sieve_binary *sbin);
25 void sieve_binary_unref(struct sieve_binary **_sbin);
26
27 void sieve_binary_close(struct sieve_binary **_sbin);
28
29 /*
30 * Resource usage
31 */
32
33 void sieve_binary_get_resource_usage(struct sieve_binary *sbin,
34 struct sieve_resource_usage *rusage_r);
35 bool sieve_binary_record_resource_usage(
36 struct sieve_binary *sbin, const struct sieve_resource_usage *rusage)
37 ATTR_NULL(1);
38 void sieve_binary_set_resource_usage(struct sieve_binary *sbin,
39 const struct sieve_resource_usage *rusage);
40 /*
41 * Accessors
42 */
43
44 pool_t sieve_binary_pool(struct sieve_binary *sbin);
45 struct sieve_instance *sieve_binary_svinst(struct sieve_binary *sbin);
46 const char *sieve_binary_path(struct sieve_binary *sbin);
47 struct sieve_script *sieve_binary_script(struct sieve_binary *sbin);
48
49 time_t sieve_binary_mtime(struct sieve_binary *sbin);
50 const struct stat *sieve_binary_stat(struct sieve_binary *sbin);
51
52 const char *sieve_binary_script_name(struct sieve_binary *sbin);
53 const char *sieve_binary_script_location(struct sieve_binary *sbin);
54
55 const char *sieve_binary_source(struct sieve_binary *sbin);
56 bool sieve_binary_loaded(struct sieve_binary *sbin);
57 bool sieve_binary_saved(struct sieve_binary *sbin);
58
59 /*
60 * Utility
61 */
62
63 const char *sieve_binfile_from_name(const char *name);
64
65 /*
66 * Activation after code generation
67 */
68
69 void sieve_binary_activate(struct sieve_binary *sbin);
70
71 /*
72 * Saving the binary
73 */
74
75 int sieve_binary_save(struct sieve_binary *sbin, const char *path, bool update,
76 mode_t save_mode, enum sieve_error *error_r);
77
78 /*
79 * Loading the binary
80 */
81
82 struct sieve_binary *
83 sieve_binary_open(struct sieve_instance *svinst, const char *path,
84 struct sieve_script *script, enum sieve_error *error_r);
85 bool sieve_binary_up_to_date(struct sieve_binary *sbin,
86 enum sieve_compile_flags cpflags);
87
88 int sieve_binary_check_executable(struct sieve_binary *sbin,
89 enum sieve_error *error_r,
90 const char **client_error_r);
91
92 /*
93 * Block management
94 */
95
96 enum sieve_binary_system_block {
97 SBIN_SYSBLOCK_SCRIPT_DATA,
98 SBIN_SYSBLOCK_EXTENSIONS,
99 SBIN_SYSBLOCK_MAIN_PROGRAM,
100 SBIN_SYSBLOCK_LAST
101 };
102
103 struct sieve_binary_block *sieve_binary_block_create(struct sieve_binary *sbin);
104
105 unsigned int sieve_binary_block_count(struct sieve_binary *sbin);
106
107 struct sieve_binary_block *
108 sieve_binary_block_get(struct sieve_binary *sbin, unsigned int id);
109
110 void sieve_binary_block_clear(struct sieve_binary_block *sblock);
111
112 size_t sieve_binary_block_get_size(const struct sieve_binary_block *sblock);
113
114 struct sieve_binary *
115 sieve_binary_block_get_binary(const struct sieve_binary_block *sblock);
116
117 unsigned int sieve_binary_block_get_id(const struct sieve_binary_block *sblock);
118
119 /*
120 * Extension support
121 */
122
123 struct sieve_binary_extension {
124 const struct sieve_extension_def *extension;
125
126 bool (*binary_pre_save)(const struct sieve_extension *ext,
127 struct sieve_binary *sbin, void *context,
128 enum sieve_error *error_r);
129 bool (*binary_post_save)(const struct sieve_extension *ext,
130 struct sieve_binary *sbin, void *context,
131 enum sieve_error *error_r);
132 bool (*binary_open)(const struct sieve_extension *ext,
133 struct sieve_binary *sbin, void *context);
134
135 void (*binary_free)(const struct sieve_extension *ext,
136 struct sieve_binary *sbin, void *context);
137
138 bool (*binary_up_to_date)(const struct sieve_extension *ext,
139 struct sieve_binary *sbin, void *context,
140 enum sieve_compile_flags cpflags);
141 };
142
143 void sieve_binary_extension_set_context(struct sieve_binary *sbin,
144 const struct sieve_extension *ext,
145 void *context);
146 const void *
147 sieve_binary_extension_get_context(struct sieve_binary *sbin,
148 const struct sieve_extension *ext);
149
150 void sieve_binary_extension_set(struct sieve_binary *sbin,
151 const struct sieve_extension *ext,
152 const struct sieve_binary_extension *bext,
153 void *context);
154
155 struct sieve_binary_block *
156 sieve_binary_extension_create_block(struct sieve_binary *sbin,
157 const struct sieve_extension *ext);
158 struct sieve_binary_block *
159 sieve_binary_extension_get_block(struct sieve_binary *sbin,
160 const struct sieve_extension *ext);
161
162 int sieve_binary_extension_link(struct sieve_binary *sbin,
163 const struct sieve_extension *ext);
164 const struct sieve_extension *
165 sieve_binary_extension_get_by_index(struct sieve_binary *sbin, int index);
166 int sieve_binary_extension_get_index(struct sieve_binary *sbin,
167 const struct sieve_extension *ext);
168 int sieve_binary_extensions_count(struct sieve_binary *sbin);
169
170 /*
171 * Code emission
172 */
173
174 /* Low-level emission functions */
175
176 sieve_size_t sieve_binary_emit_data(struct sieve_binary_block *sblock,
177 const void *data, sieve_size_t size);
178 sieve_size_t sieve_binary_emit_byte(struct sieve_binary_block *sblock,
179 uint8_t byte);
180 void sieve_binary_update_data(struct sieve_binary_block *sblock,
181 sieve_size_t address, const void *data,
182 sieve_size_t size);
183
184 /* Offset emission functions */
185
186 sieve_size_t sieve_binary_emit_offset(struct sieve_binary_block *sblock,
187 sieve_offset_t offset);
188 void sieve_binary_resolve_offset(struct sieve_binary_block *sblock,
189 sieve_size_t address);
190
191 /* Literal emission functions */
192
193 sieve_size_t sieve_binary_emit_integer(struct sieve_binary_block *sblock,
194 sieve_number_t integer);
195 sieve_size_t sieve_binary_emit_string(struct sieve_binary_block *sblock,
196 const string_t *str);
197 sieve_size_t sieve_binary_emit_cstring(struct sieve_binary_block *sblock,
198 const char *str);
199
200 static inline sieve_size_t
sieve_binary_emit_unsigned(struct sieve_binary_block * sblock,unsigned int count)201 sieve_binary_emit_unsigned(struct sieve_binary_block *sblock,
202 unsigned int count)
203 {
204 return sieve_binary_emit_integer(sblock, count);
205 }
206
207 /* Extension emission functions */
208
209 sieve_size_t sieve_binary_emit_extension(struct sieve_binary_block *sblock,
210 const struct sieve_extension *ext,
211 unsigned int offset);
212 void sieve_binary_emit_extension_object(
213 struct sieve_binary_block *sblock,
214 const struct sieve_extension_objects *objs, unsigned int code);
215
216 /*
217 * Code retrieval
218 */
219
220 /* Literals */
221
222 bool sieve_binary_read_byte(struct sieve_binary_block *sblock,
223 sieve_size_t *address, unsigned int *byte_r)
224 ATTR_NULL(3);
225 bool sieve_binary_read_code(struct sieve_binary_block *sblock,
226 sieve_size_t *address, signed int *code_r)
227 ATTR_NULL(3);
228 bool sieve_binary_read_offset(struct sieve_binary_block *sblock,
229 sieve_size_t *address, sieve_offset_t *offset_r)
230 ATTR_NULL(3);
231 bool sieve_binary_read_integer(struct sieve_binary_block *sblock,
232 sieve_size_t *address, sieve_number_t *int_r)
233 ATTR_NULL(3);
234 bool sieve_binary_read_string(struct sieve_binary_block *sblock,
235 sieve_size_t *address, string_t **str_r)
236 ATTR_NULL(3);
237
238 static inline bool ATTR_NULL(3)
sieve_binary_read_unsigned(struct sieve_binary_block * sblock,sieve_size_t * address,unsigned int * count_r)239 sieve_binary_read_unsigned(struct sieve_binary_block *sblock,
240 sieve_size_t *address, unsigned int *count_r)
241 {
242 sieve_number_t integer = 0;
243
244 if (!sieve_binary_read_integer(sblock, address, &integer))
245 return FALSE;
246 if (count_r != NULL)
247 *count_r = integer;
248 return TRUE;
249 }
250
251 /* Extensions */
252
253 bool sieve_binary_read_extension(struct sieve_binary_block *sblock,
254 sieve_size_t *address, unsigned int *offset_r,
255 const struct sieve_extension **ext_r);
256 const void *
257 sieve_binary_read_extension_object(struct sieve_binary_block *sblock,
258 sieve_size_t *address,
259 const struct sieve_extension_objects *objs);
260
261 /*
262 * Debug info
263 */
264
265 /* Writer */
266
267 struct sieve_binary_debug_writer;
268
269 struct sieve_binary_debug_writer *
270 sieve_binary_debug_writer_init(struct sieve_binary_block *sblock);
271 void sieve_binary_debug_writer_deinit(
272 struct sieve_binary_debug_writer **dwriter);
273
274 void sieve_binary_debug_emit(struct sieve_binary_debug_writer *dwriter,
275 sieve_size_t code_address, unsigned int code_line,
276 unsigned int code_column);
277
278 /* Reader */
279
280 struct sieve_binary_debug_reader *
281 sieve_binary_debug_reader_init(struct sieve_binary_block *sblock);
282 void sieve_binary_debug_reader_deinit(
283 struct sieve_binary_debug_reader **dreader);
284
285 void sieve_binary_debug_reader_reset(struct sieve_binary_debug_reader *dreader);
286
287 unsigned int
288 sieve_binary_debug_read_line(struct sieve_binary_debug_reader *dreader,
289 sieve_size_t code_address);
290
291 #endif
292