summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-sieve/sieve-binary-private.h
diff options
context:
space:
mode:
Diffstat (limited to 'pigeonhole/src/lib-sieve/sieve-binary-private.h')
-rw-r--r--pigeonhole/src/lib-sieve/sieve-binary-private.h240
1 files changed, 240 insertions, 0 deletions
diff --git a/pigeonhole/src/lib-sieve/sieve-binary-private.h b/pigeonhole/src/lib-sieve/sieve-binary-private.h
new file mode 100644
index 0000000..73d2d75
--- /dev/null
+++ b/pigeonhole/src/lib-sieve/sieve-binary-private.h
@@ -0,0 +1,240 @@
+#ifndef SIEVE_BINARY_PRIVATE_H
+#define SIEVE_BINARY_PRIVATE_H
+
+#include "sieve-common.h"
+#include "sieve-binary.h"
+#include "sieve-extensions.h"
+
+#include <sys/stat.h>
+
+#define SIEVE_BINARY_FILE_LOCK_TIMEOUT 10
+
+/*
+ * Binary file
+ */
+
+enum SIEVE_BINARY_FLAGS {
+ SIEVE_BINARY_FLAG_RESOURCE_LIMIT = BIT(0),
+};
+
+struct sieve_binary_header {
+ uint32_t magic;
+ uint16_t version_major;
+ uint16_t version_minor;
+ uint32_t blocks;
+
+ uint32_t hdr_size;
+ uint32_t flags;
+
+ struct {
+ uint64_t update_time;
+ uint32_t cpu_time_msecs;
+ } resource_usage;
+};
+
+struct sieve_binary_file {
+ pool_t pool;
+ const char *path;
+ struct sieve_binary *sbin;
+
+ struct stat st;
+ int fd;
+ off_t offset;
+};
+
+void sieve_binary_file_close(struct sieve_binary_file **_file);
+
+/*
+ * Internal structures
+ */
+
+/* Extension registration */
+
+struct sieve_binary_extension_reg {
+ /* The identifier of the extension within this binary */
+ int index;
+
+ /* Global extension object */
+ const struct sieve_extension *extension;
+
+ /* Extension to the binary; typically used to manage extension-specific
+ blocks in the binary and as a means to get a binary_free notification
+ to release references held by extensions.
+ */
+ const struct sieve_binary_extension *binext;
+
+ /* Context data associated to the binary by this extension */
+ void *context;
+
+ /* Main block for this extension */
+ unsigned int block_id;
+};
+
+/* Block */
+
+struct sieve_binary_block {
+ struct sieve_binary *sbin;
+ unsigned int id;
+ int ext_index;
+
+ buffer_t *data;
+
+ uoff_t offset;
+};
+
+/*
+ * Binary object
+ */
+
+struct sieve_binary {
+ pool_t pool;
+ int refcount;
+ struct sieve_instance *svinst;
+ struct event *event;
+
+ struct sieve_script *script;
+
+ struct sieve_binary_file *file;
+ struct sieve_binary_header header;
+ struct sieve_resource_usage rusage;
+
+ /* When the binary is loaded into memory or when it is being constructed
+ by the generator, extensions can be associated to the binary. The
+ extensions array is a sequential list of all linked extensions. The
+ extension_index array is a mapping ext_id -> binary_extension. This
+ is used to obtain the index code associated with an extension for
+ this particular binary. The linked_extensions list all extensions
+ linked to this binary object other than the preloaded language
+ features implemented as 'extensions'.
+
+ All arrays refer to the same extension registration objects. Upon
+ loading a binary, the 'require'd extensions will sometimes need to
+ associate context data to the binary object in memory. This is stored
+ in these registration objects as well.
+ */
+ ARRAY(struct sieve_binary_extension_reg *) extensions;
+ ARRAY(struct sieve_binary_extension_reg *) extension_index;
+ ARRAY(struct sieve_binary_extension_reg *) linked_extensions;
+
+ /* Attributes of a loaded binary */
+ const char *path;
+
+ /* Blocks */
+ ARRAY(struct sieve_binary_block *) blocks;
+
+ bool rusage_updated:1;
+};
+
+void sieve_binary_update_event(struct sieve_binary *sbin, const char *new_path)
+ ATTR_NULL(2);
+
+struct sieve_binary *
+sieve_binary_create(struct sieve_instance *svinst, struct sieve_script *script);
+
+/* Blocks management */
+
+static inline struct sieve_binary_block *
+sieve_binary_block_index(struct sieve_binary *sbin, unsigned int id)
+{
+ struct sieve_binary_block * const *sblock;
+
+ if (id >= array_count(&sbin->blocks))
+ return NULL;
+
+ sblock = array_idx(&sbin->blocks, id);
+ if (*sblock == NULL)
+ return NULL;
+ return *sblock;
+}
+
+static inline size_t
+_sieve_binary_block_get_size(const struct sieve_binary_block *sblock)
+{
+ return buffer_get_used_size(sblock->data);
+}
+
+struct sieve_binary_block *
+sieve_binary_block_create_id(struct sieve_binary *sbin, unsigned int id);
+
+buffer_t *sieve_binary_block_get_buffer(struct sieve_binary_block *sblock);
+
+/* Extension registration */
+
+static inline struct sieve_binary_extension_reg *
+sieve_binary_extension_create_reg(struct sieve_binary *sbin,
+ const struct sieve_extension *ext)
+{
+ int index = array_count(&sbin->extensions);
+ struct sieve_binary_extension_reg *ereg;
+
+ if (ext->id < 0)
+ return NULL;
+
+ ereg = p_new(sbin->pool, struct sieve_binary_extension_reg, 1);
+ ereg->index = index;
+ ereg->extension = ext;
+
+ array_idx_set(&sbin->extensions, (unsigned int) index, &ereg);
+ array_idx_set(&sbin->extension_index, (unsigned int) ext->id, &ereg);
+
+ return ereg;
+}
+
+static inline struct sieve_binary_extension_reg *
+sieve_binary_extension_get_reg(struct sieve_binary *sbin,
+ const struct sieve_extension *ext,
+ bool create)
+{
+ struct sieve_binary_extension_reg *reg = NULL;
+
+ if (ext->id >= 0 &&
+ ext->id < (int)array_count(&sbin->extension_index)) {
+ struct sieve_binary_extension_reg * const *ereg =
+ array_idx(&sbin->extension_index,
+ (unsigned int)ext->id);
+
+ reg = *ereg;
+ }
+
+ /* Register if not known */
+ if (reg == NULL && create)
+ return sieve_binary_extension_create_reg(sbin, ext);
+ return reg;
+}
+
+static inline int
+sieve_binary_extension_register(struct sieve_binary *sbin,
+ const struct sieve_extension *ext,
+ struct sieve_binary_extension_reg **reg_r)
+{
+ struct sieve_binary_extension_reg *ereg;
+
+ if ((ereg = sieve_binary_extension_get_reg(sbin, ext, FALSE)) == NULL) {
+ ereg = sieve_binary_extension_create_reg(sbin, ext);
+
+ if (ereg == NULL)
+ return -1;
+
+ array_append(&sbin->linked_extensions, &ereg, 1);
+ }
+
+ if (reg_r != NULL)
+ *reg_r = ereg;
+ return ereg->index;
+}
+
+/* Load/Save */
+
+bool sieve_binary_load_block(struct sieve_binary_block *);
+
+/*
+ * Resource limits
+ */
+
+bool sieve_binary_check_resource_usage(struct sieve_binary *sbin);
+
+int sieve_binary_file_update_resource_usage(struct sieve_binary *sbin,
+ enum sieve_error *error_r)
+ ATTR_NULL(2);
+
+#endif