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