diff options
Diffstat (limited to 'pigeonhole/src/lib-sieve/sieve-code.h')
-rw-r--r-- | pigeonhole/src/lib-sieve/sieve-code.h | 351 |
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 |