summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-sieve/sieve-code.h
diff options
context:
space:
mode:
Diffstat (limited to 'pigeonhole/src/lib-sieve/sieve-code.h')
-rw-r--r--pigeonhole/src/lib-sieve/sieve-code.h351
1 files changed, 351 insertions, 0 deletions
diff --git a/pigeonhole/src/lib-sieve/sieve-code.h b/pigeonhole/src/lib-sieve/sieve-code.h
new file mode 100644
index 0000000..00bf68b
--- /dev/null
+++ b/pigeonhole/src/lib-sieve/sieve-code.h
@@ -0,0 +1,351 @@
+#ifndef SIEVE_CODE_H
+#define SIEVE_CODE_H
+
+#include "lib.h"
+#include "buffer.h"
+#include "mempool.h"
+#include "array.h"
+
+#include "sieve-common.h"
+#include "sieve-runtime.h"
+#include "sieve-runtime-trace.h"
+#include "sieve-dump.h"
+
+/*
+ * Operand object
+ */
+
+struct sieve_operand_class {
+ const char *name;
+};
+
+struct sieve_operand_def {
+ const char *name;
+
+ const struct sieve_extension_def *ext_def;
+ unsigned int code;
+
+ const struct sieve_operand_class *class;
+ const void *interface;
+};
+
+struct sieve_operand {
+ const struct sieve_operand_def *def;
+ const struct sieve_extension *ext;
+ sieve_size_t address;
+ const char *field_name;
+};
+
+#define sieve_operand_name(opr) \
+ ( (opr)->def == NULL ? "(NULL)" : (opr)->def->name )
+#define sieve_operand_is(opr, definition) \
+ ( (opr)->def == &(definition) )
+
+sieve_size_t sieve_operand_emit
+ (struct sieve_binary_block *sblock, const struct sieve_extension *ext,
+ const struct sieve_operand_def *oprnd);
+bool sieve_operand_read
+ (struct sieve_binary_block *sblock, sieve_size_t *address,
+ const char *field_name, struct sieve_operand *oprnd);
+
+static inline int sieve_operand_runtime_read
+(const struct sieve_runtime_env *renv, sieve_size_t *address,
+ const char *field_name, struct sieve_operand *operand)
+{
+ if ( !sieve_operand_read(renv->sblock, address, field_name, operand) ) {
+ sieve_runtime_trace_operand_error(renv, operand, "invalid operand");
+ return SIEVE_EXEC_BIN_CORRUPT;
+ }
+
+ return SIEVE_EXEC_OK;
+}
+
+/*
+ * Optional operands
+ */
+
+int sieve_opr_optional_next
+(struct sieve_binary_block *sblock, sieve_size_t *address,
+ signed int *opt_code);
+
+static inline int sieve_opr_optional_dump
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
+ signed int *opt_code)
+{
+ sieve_size_t pc = *address;
+ int ret;
+
+ if ( (ret=sieve_opr_optional_next(denv->sblock, address, opt_code)) <= 0 )
+ return ret;
+
+ sieve_code_mark_specific(denv, pc);
+ return ret;
+}
+
+static inline int sieve_opr_optional_read
+(const struct sieve_runtime_env *renv, sieve_size_t *address,
+ signed int *opt_code)
+{
+ int ret;
+
+ if ( (ret=sieve_opr_optional_next(renv->sblock, address, opt_code)) < 0 )
+ sieve_runtime_trace_error(renv, "invalid optional operand code");
+
+ return ret;
+}
+
+/*
+ * Core operands
+ */
+
+/* Operand codes */
+
+enum sieve_core_operand {
+ SIEVE_OPERAND_OPTIONAL = 0x00,
+ SIEVE_OPERAND_NUMBER,
+ SIEVE_OPERAND_STRING,
+ SIEVE_OPERAND_STRING_LIST,
+ SIEVE_OPERAND_COMPARATOR,
+ SIEVE_OPERAND_MATCH_TYPE,
+ SIEVE_OPERAND_ADDRESS_PART,
+ SIEVE_OPERAND_CATENATED_STRING,
+
+ SIEVE_OPERAND_CUSTOM
+};
+
+/* Operand classes */
+
+extern const struct sieve_operand_class number_class;
+extern const struct sieve_operand_class string_class;
+extern const struct sieve_operand_class stringlist_class;
+
+/* Operand objects */
+
+extern const struct sieve_operand_def omitted_operand;
+extern const struct sieve_operand_def number_operand;
+extern const struct sieve_operand_def string_operand;
+extern const struct sieve_operand_def stringlist_operand;
+extern const struct sieve_operand_def catenated_string_operand;
+
+extern const struct sieve_operand_def *sieve_operands[];
+extern const unsigned int sieve_operand_count;
+
+/* Operand object interfaces */
+
+struct sieve_opr_number_interface {
+ bool (*dump)
+ (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd,
+ sieve_size_t *address);
+ int (*read)
+ (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd,
+ sieve_size_t *address, sieve_number_t *number_r);
+};
+
+struct sieve_opr_string_interface {
+ bool (*dump)
+ (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd,
+ sieve_size_t *address);
+ int (*read)
+ (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd,
+ sieve_size_t *address, string_t **str_r);
+};
+
+struct sieve_opr_stringlist_interface {
+ bool (*dump)
+ (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd,
+ sieve_size_t *address);
+ int (*read)
+ (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd,
+ sieve_size_t *address, struct sieve_stringlist **strlist_r);
+};
+
+/*
+ * Core operand functions
+ */
+
+/* Omitted */
+
+void sieve_opr_omitted_emit(struct sieve_binary_block *sblock);
+
+static inline bool sieve_operand_is_omitted
+(const struct sieve_operand *operand)
+{
+ return ( operand != NULL && operand->def != NULL &&
+ operand->def == &omitted_operand );
+}
+
+/* Number */
+
+void sieve_opr_number_emit
+ (struct sieve_binary_block *sblock, sieve_number_t number);
+bool sieve_opr_number_dump_data
+ (const struct sieve_dumptime_env *denv, struct sieve_operand *operand,
+ sieve_size_t *address, const char *field_name);
+bool sieve_opr_number_dump
+ (const struct sieve_dumptime_env *denv, sieve_size_t *address,
+ const char *field_name);
+int sieve_opr_number_read_data
+ (const struct sieve_runtime_env *renv, struct sieve_operand *operand,
+ sieve_size_t *address, const char *field_name, sieve_number_t *number_r);
+int sieve_opr_number_read
+ (const struct sieve_runtime_env *renv, sieve_size_t *address,
+ const char *field_name, sieve_number_t *number_r);
+
+static inline bool sieve_operand_is_number
+(const struct sieve_operand *operand)
+{
+ return ( operand != NULL && operand->def != NULL &&
+ operand->def->class == &number_class );
+}
+
+/* String */
+
+void sieve_opr_string_emit
+ (struct sieve_binary_block *sblock, string_t *str);
+bool sieve_opr_string_dump_data
+ (const struct sieve_dumptime_env *denv, struct sieve_operand *operand,
+ sieve_size_t *address, const char *field_name);
+bool sieve_opr_string_dump
+ (const struct sieve_dumptime_env *denv, sieve_size_t *address,
+ const char *field_name);
+bool sieve_opr_string_dump_ex
+ (const struct sieve_dumptime_env *denv, sieve_size_t *address,
+ const char *field_name, const char *omitted_value);
+int sieve_opr_string_read_data
+ (const struct sieve_runtime_env *renv, struct sieve_operand *operand,
+ sieve_size_t *address, const char *field_name, string_t **str_r);
+int sieve_opr_string_read
+ (const struct sieve_runtime_env *renv, sieve_size_t *address,
+ const char *field_name, string_t **str_r);
+int sieve_opr_string_read_ex
+ (const struct sieve_runtime_env *renv, sieve_size_t *address,
+ const char *field_name, bool optional, string_t **str_r, bool *literal_r);
+
+static inline bool sieve_operand_is_string
+(const struct sieve_operand *operand)
+{
+ return ( operand != NULL && operand->def != NULL &&
+ operand->def->class == &string_class );
+}
+
+static inline bool sieve_operand_is_string_literal
+(const struct sieve_operand *operand)
+{
+ return ( operand != NULL && sieve_operand_is(operand, string_operand) );
+}
+
+/* String list */
+
+void sieve_opr_stringlist_emit_start
+ (struct sieve_binary_block *sblock, unsigned int listlen, void **context);
+void sieve_opr_stringlist_emit_item
+ (struct sieve_binary_block *sblock, void *context ATTR_UNUSED,
+ string_t *item);
+void sieve_opr_stringlist_emit_end
+ (struct sieve_binary_block *sblock, void *context);
+bool sieve_opr_stringlist_dump_data
+ (const struct sieve_dumptime_env *denv, struct sieve_operand *operand,
+ sieve_size_t *address, const char *field_name);
+bool sieve_opr_stringlist_dump
+ (const struct sieve_dumptime_env *denv, sieve_size_t *address,
+ const char *field_name);
+bool sieve_opr_stringlist_dump_ex
+ (const struct sieve_dumptime_env *denv, sieve_size_t *address,
+ const char *field_name, const char *omitted_value);
+int sieve_opr_stringlist_read_data
+ (const struct sieve_runtime_env *renv, struct sieve_operand *operand,
+ sieve_size_t *address, const char *field_name,
+ struct sieve_stringlist **strlist_r);
+int sieve_opr_stringlist_read
+ (const struct sieve_runtime_env *renv, sieve_size_t *address,
+ const char *field_name, struct sieve_stringlist **strlist_r);
+int sieve_opr_stringlist_read_ex
+ (const struct sieve_runtime_env *renv, sieve_size_t *address,
+ const char *field_name, bool optional, struct sieve_stringlist **strlist_r);
+
+static inline bool sieve_operand_is_stringlist
+(const struct sieve_operand *operand)
+{
+ return ( operand != NULL && operand->def != NULL &&
+ (operand->def->class == &stringlist_class ||
+ operand->def->class == &string_class) );
+}
+
+/* Catenated string */
+
+void sieve_opr_catenated_string_emit
+ (struct sieve_binary_block *sblock, unsigned int elements);
+
+/*
+ * Operation object
+ */
+
+struct sieve_operation_def {
+ const char *mnemonic;
+
+ const struct sieve_extension_def *ext_def;
+ unsigned int code;
+
+ bool (*dump)
+ (const struct sieve_dumptime_env *denv, sieve_size_t *address);
+ int (*execute)
+ (const struct sieve_runtime_env *renv, sieve_size_t *address);
+};
+
+struct sieve_operation {
+ const struct sieve_operation_def *def;
+ const struct sieve_extension *ext;
+
+ sieve_size_t address;
+};
+
+#define sieve_operation_is(oprtn, definition) \
+ ( (oprtn)->def == &(definition) )
+#define sieve_operation_mnemonic(oprtn) \
+ ( (oprtn)->def == NULL ? "(NULL)" : (oprtn)->def->mnemonic )
+
+sieve_size_t sieve_operation_emit
+ (struct sieve_binary_block *sblock, const struct sieve_extension *ext,
+ const struct sieve_operation_def *op_def);
+bool sieve_operation_read
+ (struct sieve_binary_block *sblock, sieve_size_t *address,
+ struct sieve_operation *oprtn);
+const char *sieve_operation_read_string
+ (struct sieve_binary_block *sblock, sieve_size_t *address);
+
+/*
+ * Core operations
+ */
+
+/* Opcodes */
+
+enum sieve_operation_code {
+ SIEVE_OPERATION_INVALID,
+ SIEVE_OPERATION_JMP,
+ SIEVE_OPERATION_JMPTRUE,
+ SIEVE_OPERATION_JMPFALSE,
+
+ SIEVE_OPERATION_STOP,
+ SIEVE_OPERATION_KEEP,
+ SIEVE_OPERATION_DISCARD,
+ SIEVE_OPERATION_REDIRECT,
+
+ SIEVE_OPERATION_ADDRESS,
+ SIEVE_OPERATION_HEADER,
+ SIEVE_OPERATION_EXISTS,
+ SIEVE_OPERATION_SIZE_OVER,
+ SIEVE_OPERATION_SIZE_UNDER,
+
+ SIEVE_OPERATION_CUSTOM
+};
+
+/* Operation objects */
+
+extern const struct sieve_operation_def sieve_jmp_operation;
+extern const struct sieve_operation_def sieve_jmptrue_operation;
+extern const struct sieve_operation_def sieve_jmpfalse_operation;
+
+extern const struct sieve_operation_def *sieve_operations[];
+extern const unsigned int sieve_operations_count;
+
+#endif