summaryrefslogtreecommitdiff
path: root/libmu_sieve/sieve-priv.h
blob: 041b4ea7c3792f7407ca33cf4a9e227b419ea206 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/* GNU Mailutils -- a suite of utilities for electronic mail
   Copyright (C) 1999-2002, 2005-2012, 2014-2017 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
   <http://www.gnu.org/licenses/>. */

#include <mailutils/sieve.h>
#include <mailutils/assoc.h>
#include <setjmp.h>
#include <string.h>
#include <regex.h>

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;
  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 registry;        /* Tests, Actions, Comparators */

  char **idspace;            /* Source and identifier names */
  size_t idcount;
  size_t idmax;
  
  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; /* Machine state */
  size_t pc;                 /* Current program counter */
  long reg;                  /* Numeric register */

  /* Support for variables (RFC 5229) */
  mu_assoc_t vartab;         /* Table of variables */
  char *match_string;        /* The string used in the most recent match */
  regmatch_t *match_buf;     /* Offsets of parenthesized groups */
  size_t match_count;        /* Actual number of elements used in match_buf */
  size_t match_max;          /* Total number of elements available in match_buf */

  /* 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_assoc_t exenv;          /* Execution environment (RFC 5183) */

  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,
    mu_sieve_node_end,
  };

struct mu_sieve_node
{
  struct mu_sieve_node *prev, *next;
  enum mu_sieve_node_type type;
  struct mu_locus_range locus;
  union
  {
    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_registry_t *reg;
      size_t argstart;
      size_t argcount;
      size_t tagcount;
      mu_sieve_comparator_t comparator; /* Comparator (for tests) */
    } command;
  } v;
};

struct mu_sieve_node_list
{
  struct mu_sieve_node *head, *tail;
};

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 (void);

extern mu_sieve_machine_t mu_sieve_machine;

void mu_i_sv_code (struct mu_sieve_machine *mach, sieve_op_t op);

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_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_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);

char *mu_i_sv_id_canon (mu_sieve_machine_t mach, char const *name);
size_t mu_i_sv_id_num (mu_sieve_machine_t mach, char const *name);
char *mu_i_sv_id_str (mu_sieve_machine_t mach, size_t n);
void mu_i_sv_free_idspace (mu_sieve_machine_t mach);

void mu_i_sv_copy_variables (mu_sieve_machine_t child,
			     mu_sieve_machine_t parent);
int mu_i_sv_expand_variables (char const *input, size_t len,
			      char **exp, void *data);

Return to:

Send suggestions and report system problems to the System administrator.