/* GNU Mailutils -- a suite of utilities for electronic mail Copyright (C) 1999-2002, 2005-2012, 2014-2016 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include #include typedef void (*sieve_instr_t) (mu_sieve_machine_t mach); typedef union { sieve_instr_t instr; mu_sieve_handler_t handler; mu_sieve_value_t *val; mu_sieve_comparator_t comp; mu_list_t list; long number; size_t pc; size_t line; int inum; char *string; unsigned unum; } sieve_op_t; struct mu_locus_range { struct mu_locus beg; struct mu_locus end; }; #define YYLTYPE struct mu_locus_range #define MU_SV_SAVED_ERR_STATE 0x01 #define MU_SV_SAVED_DBG_STATE 0x02 #define MU_SV_SAVED_STATE 0x80 enum mu_sieve_state { mu_sieve_state_init, mu_sieve_state_error, mu_sieve_state_compiled, mu_sieve_state_running, mu_sieve_state_disass }; struct mu_sieve_machine { /* Static data */ struct mu_locus locus; /* Approximate location in the code */ mu_list_t memory_pool; /* Pool of allocated memory objects */ mu_list_t destr_list; /* List of destructor functions */ /* Symbol space: */ mu_opool_t string_pool; /* String constants */ mu_list_t test_list; /* Tests */ mu_list_t action_list; /* Actions */ mu_list_t comp_list; /* Comparators */ mu_list_t source_list; /* Source names (for diagnostics) */ mu_sieve_string_t *stringspace; size_t stringcount; size_t stringmax; mu_sieve_value_t *valspace; size_t valcount; size_t valmax; size_t progsize; /* Number of allocated program cells */ sieve_op_t *prog; /* Compiled program */ /* Runtime data */ enum mu_sieve_state state; size_t pc; /* Current program counter */ long reg; /* Numeric register */ mu_list_t stack; /* Runtime stack */ /* Call environment */ const char *identifier; /* Name of action or test being executed */ size_t argstart; /* Index of the first argument in valspace */ size_t argcount; /* Number of positional arguments */ size_t tagcount; /* Number of tagged arguments */ mu_sieve_comparator_t comparator; /* Comparator (for tests) */ int dry_run; /* Dry-run mode */ jmp_buf errbuf; /* Target location for non-local exits */ mu_mailbox_t mailbox; /* Mailbox to operate upon */ size_t msgno; /* Current message number */ mu_message_t msg; /* Current message */ int action_count; /* Number of actions executed over this message */ /* Stream state info */ int state_flags; int err_mode; struct mu_locus err_locus; int dbg_mode; struct mu_locus dbg_locus; /* User supplied data */ mu_stream_t errstream; mu_stream_t dbgstream; mu_sieve_action_log_t logger; mu_mailer_t mailer; char *daemon_email; void *data; }; enum mu_sieve_node_type { mu_sieve_node_noop, mu_sieve_node_false, mu_sieve_node_true, mu_sieve_node_test, mu_sieve_node_action, mu_sieve_node_cond, mu_sieve_node_anyof, mu_sieve_node_allof, mu_sieve_node_not, }; struct mu_sieve_node { struct mu_sieve_node *prev, *next; enum mu_sieve_node_type type; struct mu_locus_range locus; union { mu_sieve_value_t *value; mu_list_t list; struct mu_sieve_node *node; struct { struct mu_sieve_node *expr; struct mu_sieve_node *iftrue; struct mu_sieve_node *iffalse; } cond; struct { mu_sieve_register_t *reg; size_t argstart; size_t argcount; size_t tagcount; mu_sieve_comparator_t comparator; /* Comparator (for tests) */ } command; } v; }; int mu_sieve_yyerror (const char *s); int mu_sieve_yylex (void); int mu_i_sv_lex_begin (const char *name); int mu_i_sv_lex_begin_string (const char *buf, int bufsize, const char *fname, int line); void mu_i_sv_lex_finish (struct mu_sieve_machine *mach); extern mu_sieve_machine_t mu_sieve_machine; void mu_i_sv_code (struct mu_sieve_machine *mach, sieve_op_t op); void mu_i_sv_compile_error (struct mu_sieve_machine *mach, const char *fmt, ...) MU_PRINTFLIKE(2,3); int mu_i_sv_locus (struct mu_sieve_machine *mach, struct mu_locus_range *lr); void mu_i_sv_code_action (struct mu_sieve_machine *mach, struct mu_sieve_node *node); void mu_i_sv_code_test (struct mu_sieve_machine *mach, struct mu_sieve_node *node); /* Opcodes */ void _mu_i_sv_instr_action (mu_sieve_machine_t mach); void _mu_i_sv_instr_test (mu_sieve_machine_t mach); void _mu_i_sv_instr_push (mu_sieve_machine_t mach); void _mu_i_sv_instr_pop (mu_sieve_machine_t mach); void _mu_i_sv_instr_not (mu_sieve_machine_t mach); void _mu_i_sv_instr_branch (mu_sieve_machine_t mach); void _mu_i_sv_instr_brz (mu_sieve_machine_t mach); void _mu_i_sv_instr_brnz (mu_sieve_machine_t mach); void _mu_i_sv_instr_source (mu_sieve_machine_t mach); void _mu_i_sv_instr_line (mu_sieve_machine_t mach); int mu_i_sv_load_add_dir (mu_sieve_machine_t mach, const char *name); void mu_i_sv_register_standard_actions (mu_sieve_machine_t mach); void mu_i_sv_register_standard_tests (mu_sieve_machine_t mach); void mu_i_sv_register_standard_comparators (mu_sieve_machine_t mach); void mu_i_sv_print_value_list (mu_list_t list, mu_stream_t str); void mu_i_sv_print_tag_list (mu_list_t list, mu_stream_t str); void mu_i_sv_error (mu_sieve_machine_t mach); void mu_i_sv_debug (mu_sieve_machine_t mach, size_t pc, const char *fmt, ...) MU_PRINTFLIKE(3,4); void mu_i_sv_debug_command (mu_sieve_machine_t mach, size_t pc, char const *what); void mu_i_sv_trace (mu_sieve_machine_t mach, const char *what); void mu_i_sv_valf (mu_sieve_machine_t mach, mu_stream_t str, mu_sieve_value_t *val); typedef int (*mu_i_sv_interp_t) (char const *, size_t, char **, void *); int mu_i_sv_string_expand (char const *input, mu_i_sv_interp_t interp, void *data, char **ret); int mu_i_sv_expand_encoded_char (char const *input, size_t len, char **exp, void *data); int mu_sieve_require_encoded_character (mu_sieve_machine_t mach, const char *name); void mu_i_sv_2nrealloc (mu_sieve_machine_t mach, void **pptr, size_t *pnmemb, size_t size); mu_sieve_value_t *mu_i_sv_mach_arg (mu_sieve_machine_t mach, size_t n); mu_sieve_value_t *mu_i_sv_mach_tagn (mu_sieve_machine_t mach, size_t n); void mu_i_sv_lint_command (struct mu_sieve_machine *mach, struct mu_sieve_node *node); size_t mu_i_sv_string_create (mu_sieve_machine_t mach, char *str);