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
|
/*-
* Copyright 2016 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SRC_LIBUTIL_EXPRESSION_H_
#define SRC_LIBUTIL_EXPRESSION_H_
#include "config.h"
#include "mem_pool.h"
#include "fstring.h"
#define RSPAMD_EXPRESSION_MAX_PRIORITY 1024
#define RSPAMD_EXPRESSION_FLAG_NOOPT (1 << 0)
enum rspamd_expression_op {
OP_INVALID = 0,
OP_PLUS, /* || or + */
OP_MULT, /* && or * */
OP_OR, /* || or | */
OP_AND, /* && or & */
OP_NOT, /* ! */
OP_LT, /* < */
OP_GT, /* > */
OP_LE, /* <= */
OP_GE, /* >= */
OP_OBRACE, /* ( */
OP_CBRACE /* ) */
};
typedef struct rspamd_expression_atom_s {
/* Parent node */
GNode *parent;
/* Opaque userdata */
gpointer data;
/* String representation of atom */
const gchar *str;
/* Length of the string representation of atom */
gsize len;
/* Average execution time (in ticks) */
gdouble avg_ticks;
/* Amount of positive triggers */
guint hits;
/* Relative priority */
gint priority;
} rspamd_expression_atom_t;
struct rspamd_atom_subr {
/* Parses atom from string and returns atom structure */
rspamd_expression_atom_t * (*parse)(const gchar *line, gsize len,
rspamd_mempool_t *pool, gpointer ud, GError **err);
/* Process atom via the opaque pointer (e.g. struct rspamd_task *) */
gdouble (*process) (gpointer input, rspamd_expression_atom_t *atom);
/* Calculates the relative priority of the expression */
gint (*priority) (rspamd_expression_atom_t *atom);
void (*destroy) (rspamd_expression_atom_t *atom);
};
/* Opaque structure */
struct rspamd_expression;
/**
* Parse symbolic expression and create the expression using the specified subroutines for atoms processing
* @param line line to parse
* @param len length of the line (if 0 then line should be NULL terminated)
* @param subr subroutines for atoms parsing
* @param subr_data opaque dat pointer
* @param pool pool to use for memory allocations
* @param err error pointer
* @param target the target expression
* @return TRUE if an expression have been parsed
*/
gboolean rspamd_parse_expression (const gchar *line, gsize len,
const struct rspamd_atom_subr *subr, gpointer subr_data,
rspamd_mempool_t *pool, GError **err,
struct rspamd_expression **target);
/**
* Process the expression and return its value using atom 'process' functions with the specified data pointer
* @param expr expression to process
* @param data opaque data pointer for all the atoms
* @return the value of expression
*/
gdouble rspamd_process_expression (struct rspamd_expression *expr, gint flags,
gpointer data);
/**
* Process the expression and return its value using atom 'process' functions with the specified data pointer.
* This function also accepts `track` argument where it writes matched atoms (those whose value is more than 0)
* @param expr expression to process
* @param data opaque data pointer for all the atoms
* @param track pointer array to atoms tracking
* @return the value of expression
*/
gdouble rspamd_process_expression_track (struct rspamd_expression *expr, gint flags,
gpointer data, GPtrArray *track);
/**
* Shows string representation of an expression
* @param expr expression to show
* @return freshly allocated string with expression
*/
GString *rspamd_expression_tostring (struct rspamd_expression *expr);
/**
* Callback that is called on @see rspamd_expression_atom_foreach, atom is ephemeral
* and should not be modified within callback
*/
typedef void (*rspamd_expression_atom_foreach_cb) (const rspamd_ftok_t *atom,
gpointer ud);
/**
* Traverse over all atoms in the expression
* @param expr expression
* @param cb callback to be called
* @param ud opaque data passed to `cb`
*/
void rspamd_expression_atom_foreach (struct rspamd_expression *expr,
rspamd_expression_atom_foreach_cb cb, gpointer cbdata);
/**
* Checks if a specified node in AST is the specified operation
* @param node AST node packed in GNode container
* @param op operation to check
* @return TRUE if node is operation node and is exactly the specified option
*/
gboolean rspamd_expression_node_is_op (GNode *node, enum rspamd_expression_op op);
#endif /* SRC_LIBUTIL_EXPRESSION_H_ */
|