summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/plugins/imapsieve/ext-imapsieve.c
blob: 64dfc07d82df80b48f374482fb9f745fb0e6903b (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
/* Copyright (c) 2016-2018 Pigeonhole authors, see the included COPYING file
 */

/* Extension imapsieve
 * -------------------
 *
 * Authors: Stephan Bosch
 * Specification: RFC 6785
 * Implementation: full
 * Status: experimental
 *
 */

#include "lib.h"

#include "sieve-extensions.h"
#include "sieve-commands.h"
#include "sieve-binary.h"

#include "sieve-validator.h"
#include "sieve-interpreter.h"

#include "sieve-ext-environment.h"

#include "ext-imapsieve-common.h"

/*
 * Extension
 */

static bool ext_imapsieve_load
	(const struct sieve_extension *ext, void **context);
static bool ext_vnd_imapsieve_load
	(const struct sieve_extension *ext, void **context);
static bool ext_vnd_imapsieve_validator_load
	(const struct sieve_extension *ext, struct sieve_validator *valdtr);

static bool ext_imapsieve_interpreter_load
	(const struct sieve_extension *ext,
		const struct sieve_runtime_env *renv,
		sieve_size_t *address ATTR_UNUSED);

#ifdef __IMAPSIEVE_DUMMY
const struct sieve_extension_def imapsieve_extension_dummy = {
#else
const struct sieve_extension_def imapsieve_extension = {
#endif
	.name = "imapsieve",
	.load = ext_imapsieve_load,
	.interpreter_load = ext_imapsieve_interpreter_load
};

#ifdef __IMAPSIEVE_DUMMY
const struct sieve_extension_def vnd_imapsieve_extension_dummy = {
#else
const struct sieve_extension_def vnd_imapsieve_extension = {
#endif
	.name = "vnd.dovecot.imapsieve",
	.load = ext_vnd_imapsieve_load,
	.interpreter_load = ext_imapsieve_interpreter_load,
	.validator_load = ext_vnd_imapsieve_validator_load
};

/*
 * Context
 */

static bool ext_imapsieve_load
(const struct sieve_extension *ext, void **context)
{
	*context = (void*)
		sieve_ext_environment_require_extension(ext->svinst);
	return TRUE;
}

static bool ext_vnd_imapsieve_load
(const struct sieve_extension *ext, void **context)
{
	*context = (void*)sieve_extension_require
#ifdef __IMAPSIEVE_DUMMY
		(ext->svinst, &imapsieve_extension_dummy, TRUE);
#else
		(ext->svinst, &imapsieve_extension, TRUE);
#endif
	return TRUE;
}

/*
 * Validator
 */

static bool ext_vnd_imapsieve_validator_load
(const struct sieve_extension *ext ATTR_UNUSED,
	struct sieve_validator *valdtr)
{
	const struct sieve_extension *ims_ext;

	/* Load environment extension implicitly */

	ims_ext = sieve_validator_extension_load_implicit
#ifdef __IMAPSIEVE_DUMMY
		(valdtr, imapsieve_extension_dummy.name);
#else
		(valdtr, imapsieve_extension.name);
#endif
	if ( ims_ext == NULL )
		return FALSE;

	return TRUE;
}

/*
 * Interpreter
 */

static int ext_imapsieve_interpreter_run
	(const struct sieve_extension *this_ext,
		const struct sieve_runtime_env *renv,
		void *context, bool deferred);

const struct sieve_interpreter_extension
imapsieve_interpreter_extension = {
#ifdef __IMAPSIEVE_DUMMY
	.ext_def = &imapsieve_extension_dummy,
#else
	.ext_def = &imapsieve_extension,
#endif
	.run = ext_imapsieve_interpreter_run
};

static bool ext_imapsieve_interpreter_load
(const struct sieve_extension *ext ATTR_UNUSED,
	const struct sieve_runtime_env *renv,
	sieve_size_t *address ATTR_UNUSED)
{
	sieve_interpreter_extension_register(renv->interp,
		ext, &imapsieve_interpreter_extension, NULL);
	return TRUE;
}

#ifdef __IMAPSIEVE_DUMMY
static int ext_imapsieve_interpreter_run
(const struct sieve_extension *ext ATTR_UNUSED,
	const struct sieve_runtime_env *renv,
	void *context ATTR_UNUSED, bool deferred)
{
	if ( !deferred ) {
		sieve_runtime_error(renv, NULL,
			"the imapsieve extension cannot be used outside IMAP");
	}
	return SIEVE_EXEC_FAILURE;
}
#else
static int ext_imapsieve_interpreter_run
(const struct sieve_extension *ext,
	const struct sieve_runtime_env *renv,
	void *context ATTR_UNUSED, bool deferred ATTR_UNUSED)
{
	if (ext->def == &vnd_imapsieve_extension) {
		const struct sieve_extension *ims_ext =
			(const struct sieve_extension *)ext->context;
		ext_imapsieve_environment_vendor_items_register(ims_ext, renv);
	} else {
		ext_imapsieve_environment_items_register(ext, renv);
	}
	return SIEVE_EXEC_OK;
}
#endif