summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-sieve/plugins/mime/ext-extracttext.c
blob: 4eab76b9d25e681b22e20572ca19b3009ff98ffd (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
/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
 */

/* Extension extracttext
 * ---------------------
 *
 * Authors: Stephan Bosch
 * Specification: RFC 5703, Section 7
 * Implementation: full
 * Status: experimental
 *
 */

#include "sieve-common.h"

#include "sieve-code.h"
#include "sieve-extensions.h"
#include "sieve-actions.h"
#include "sieve-commands.h"
#include "sieve-validator.h"
#include "sieve-generator.h"
#include "sieve-interpreter.h"
#include "sieve-result.h"

#include "sieve-ext-variables.h"

#include "ext-mime-common.h"

/*
 * Extension
 */

static bool ext_extracttext_load
	(const struct sieve_extension *ext, void **context);
static void ext_extracttext_unload
	(const struct sieve_extension *ext);
static bool ext_extracttext_validator_load
	(const struct sieve_extension *ext, struct sieve_validator *valdtr);

const struct sieve_extension_def extracttext_extension = {
	.name = "extracttext",
	.load = ext_extracttext_load,
	.unload = ext_extracttext_unload,
	.validator_load = ext_extracttext_validator_load,
	SIEVE_EXT_DEFINE_OPERATION(extracttext_operation)
};

static bool ext_extracttext_load
(const struct sieve_extension *ext, void **context)
{
	struct sieve_instance *svinst = ext->svinst;
	struct ext_extracttext_context *ectx;

	if ( *context != NULL )
		ext_extracttext_unload(ext);

	ectx = i_new(struct ext_extracttext_context, 1);
	ectx->var_ext = sieve_ext_variables_get_extension(ext->svinst);
	ectx->fep_ext = sieve_extension_register
		(svinst, &foreverypart_extension, FALSE);
	*context = (void *)ectx;
	return TRUE;
}

static void ext_extracttext_unload
(const struct sieve_extension *ext)
{
	struct ext_extracttext_context *ctx =
		(struct ext_extracttext_context *) ext->context;

	i_free(ctx);
}

/*
 * Extension validation
 */

static bool ext_extracttext_validator_validate
	(const struct sieve_extension *ext,
		struct sieve_validator *valdtr, void *context,
		struct sieve_ast_argument *require_arg,
		bool required);

const struct sieve_validator_extension
extracttext_validator_extension = {
	.ext = &extracttext_extension,
	.validate = ext_extracttext_validator_validate
};

static bool ext_extracttext_validator_load
(const struct sieve_extension *ext, struct sieve_validator *valdtr)
{
	/* Register validator extension to check for conflict with eextracttext */
	sieve_validator_extension_register
		(valdtr, ext, &extracttext_validator_extension, NULL);

	/* Register new commands */
	sieve_validator_register_command(valdtr, ext, &cmd_extracttext);

	return TRUE;
}

static bool ext_extracttext_validator_validate
(const struct sieve_extension *ext,
	struct sieve_validator *valdtr, void *context ATTR_UNUSED,
	struct sieve_ast_argument *require_arg,
	bool required ATTR_UNUSED)
{
	struct ext_extracttext_context *ectx =
		(struct ext_extracttext_context *)ext->context;

	if ( ectx->var_ext == NULL ||
		!sieve_ext_variables_is_active
			(ectx->var_ext, valdtr) ) {
		sieve_argument_validate_error(valdtr, require_arg,
			"extracttext extension cannot be used "
			"without variables extension");
		return FALSE;
	}
	if ( ectx->fep_ext == NULL ||
		!sieve_validator_extension_loaded
	    (valdtr, ectx->fep_ext) ) {
		sieve_argument_validate_error(valdtr, require_arg,
			"extracttext extension cannot be used "
			"without foreverypart extension");
		return FALSE;
	}

	return TRUE;
}