1
/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
4
#ifndef __MANAGESIEVE_PARSER_H
5
#define __MANAGESIEVE_PARSER_H
8
* QUOTED-SPECIALS = <"> / "\"
10
#define IS_QUOTED_SPECIAL(c) \
11
((c) == '"' || (c) == '\\')
14
* ATOM-SPECIALS = "(" / ")" / "{" / SP / CTL / QUOTED-SPECIALS
16
#define IS_ATOM_SPECIAL(c) \
17
((c) == '(' || (c) == ')' || (c) == '{' || \
18
(c) <= 32 || (c) == 0x7f || \
28
* TEXT-CHAR = %x01-09 / %x0B-0C / %x0E-7F
29
* ;; any CHAR except CR and LF
31
#define IS_TEXT_CHAR(c) \
32
(IS_CHAR(c) && (c) != '\r' && (c) != '\n')
35
* SAFE-CHAR = %x01-09 / %x0B-0C / %x0E-21 /
37
* ;; any TEXT-CHAR except QUOTED-SPECIALS
39
#define IS_SAFE_CHAR(c) \
40
(IS_TEXT_CHAR(c) && !IS_QUOTED_SPECIAL(c))
44
#define IS_UTF8_1(c) \
45
(((c) & 0xC0) == 0x80)
47
/* UTF8-2 = %xC0-DF UTF8-1
49
#define IS_UTF8_2S(c) \
50
(((c) & 0xE0) == 0xC0)
52
/* UTF8-3 = %xE0-EF 2UTF8-1
54
#define IS_UTF8_3S(c) \
55
(((c) & 0xF0) == 0xE0)
57
/* UTF8-4 = %xF0-F7 3UTF8-1
59
#define IS_UTF8_4S(c) \
60
(((c) & 0xF8) == 0xF0)
62
/* UTF8-5 = %xF8-FB 4UTF8-1
64
#define IS_UTF8_5S(c) \
65
(((c) & 0xFC) == 0xF8)
67
/* UTF8-6 = %xFC-FD 5UTF8-1
69
#define IS_UTF8_6S(c) \
70
(((c) & 0xFE) == 0xFC)
72
/* SAFE-UTF8-CHAR = SAFE-CHAR / UTF8-2 / UTF8-3 / UTF8-4 /
76
( IS_SAFE_CHAR(c) ? 1 : \
81
IS_UTF8_6S(c) ? 6 : 0 )
83
enum managesieve_parser_flags {
84
/* Set this flag if you wish to read only size of literal argument
85
and not convert literal into string. Useful when you need to deal
86
with large literal sizes. The literal must be the last read
88
MANAGESIEVE_PARSE_FLAG_LITERAL_SIZE = 0x01,
89
/* Don't remove '\' chars from string arguments */
90
MANAGESIEVE_PARSE_FLAG_NO_UNESCAPE = 0x02,
91
/* Return literals as MANAGESIEVE_ARG_LITERAL instead of MANAGESIEVE_ARG_STRING */
92
MANAGESIEVE_PARSE_FLAG_LITERAL_TYPE = 0x04
95
enum managesieve_arg_type {
96
MANAGESIEVE_ARG_ATOM = 0,
97
MANAGESIEVE_ARG_STRING,
99
/* literals are returned as MANAGESIEVE_ARG_STRING by default */
100
MANAGESIEVE_ARG_LITERAL,
101
MANAGESIEVE_ARG_LITERAL_SIZE,
103
MANAGESIEVE_ARG_EOL /* end of argument list */
106
struct managesieve_parser;
108
struct managesieve_arg {
109
enum managesieve_arg_type type;
117
#define MANAGESIEVE_ARG_STR(arg) \
118
((arg)->type == MANAGESIEVE_ARG_STRING || \
119
(arg)->type == MANAGESIEVE_ARG_ATOM || \
120
(arg)->type == MANAGESIEVE_ARG_LITERAL ? \
121
(arg)->_data.str : _managesieve_arg_str_error(arg))
123
#define MANAGESIEVE_ARG_LITERAL_SIZE(arg) \
124
(((arg)->type == MANAGESIEVE_ARG_LITERAL_SIZE) ? \
125
(arg)->_data.literal_size : _managesieve_arg_literal_size_error(arg))
127
struct managesieve_arg_list {
129
struct managesieve_arg args[1]; /* variable size */
133
/* Create new MANAGESIEVE argument parser. output is used for sending command
134
continuation requests for literals.
136
max_line_size can be used to approximately limit the maximum amount of
137
memory that gets allocated when parsing a line. Input buffer size limits
138
the maximum size of each parsed token.
140
Usually the largest lines are large only because they have a one huge
141
message set token, so you'll probably want to keep input buffer size the
142
same as max_line_size. That means the maximum memory usage is around
143
2 * max_line_size. */
144
struct managesieve_parser *
145
managesieve_parser_create(struct istream *input, struct ostream *output,
146
size_t max_line_size);
147
void managesieve_parser_destroy(struct managesieve_parser **parser);
149
/* Reset the parser to initial state. */
150
void managesieve_parser_reset(struct managesieve_parser *parser);
152
/* Return the last error in parser. fatal is set to TRUE if there's no way to
153
continue parsing, currently only if too large non-sync literal size was
155
const char *managesieve_parser_get_error(struct managesieve_parser *parser, bool *fatal);
157
/* Read a number of arguments. This function doesn't call i_stream_read(), you
158
need to do that. Returns number of arguments read (may be less than count
159
in case of EOL), -2 if more data is needed or -1 if error occurred.
161
count-sized array of arguments are stored into args when return value is
162
0 or larger. If all arguments weren't read, they're set to NIL. count
163
can be set to 0 to read all arguments in the line. Last element in
164
args is always of type MANAGESIEVE_ARG_EOL. */
165
int managesieve_parser_read_args(struct managesieve_parser *parser, unsigned int count,
166
enum managesieve_parser_flags flags, struct managesieve_arg **args);
168
/* just like managesieve_parser_read_args(), but assume \n at end of data in
170
int managesieve_parser_finish_line(struct managesieve_parser *parser, unsigned int count,
171
enum managesieve_parser_flags flags,
172
struct managesieve_arg **args);
174
/* Read one word - used for reading tag and command name.
175
Returns NULL if more data is needed. */
176
const char *managesieve_parser_read_word(struct managesieve_parser *parser);
178
/* Returns the managesieve argument as string. If it is no string this returns NULL */
179
const char *managesieve_arg_string(struct managesieve_arg *arg);
181
/* Returns 1 if the argument is a number. If it is no number this returns -1.
182
* The number itself is stored in *number.
184
int managesieve_arg_number
185
(struct managesieve_arg *arg, uoff_t *number);
187
/* Error functions */
188
char *_managesieve_arg_str_error(const struct managesieve_arg *arg);
189
uoff_t _managesieve_arg_literal_size_error(const struct managesieve_arg *arg);
190
struct managesieve_arg_list *_managesieve_arg_list_error(const struct managesieve_arg *arg);