summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/managesieve/managesieve-capabilities.c
blob: c72558f0c48a1824e569aede4868ed2d15674eb4 (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
/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
 */

#include "lib.h"
#include "array.h"
#include "hostpid.h"
#include "var-expand.h"
#include "settings-parser.h"
#include "master-service.h"
#include "master-service-settings.h"
#include "master-service-settings-cache.h"

#include "sieve.h"

#include "managesieve-capabilities.h"

#include <stddef.h>
#include <unistd.h>

/*
 * Global plugin settings
 */

struct plugin_settings {
	ARRAY(const char *) plugin_envs;
};

static const struct setting_parser_info **plugin_set_roots;

static const struct setting_define plugin_setting_defines[] = {
	{ .type = SET_STRLIST, .key = "plugin",
	  .offset = offsetof(struct plugin_settings, plugin_envs) },

	SETTING_DEFINE_LIST_END
};

static const struct setting_parser_info plugin_setting_parser_info = {
	.module_name = "managesieve",
	.defines = plugin_setting_defines,

	.type_offset = (size_t)-1,
	.struct_size = sizeof(struct plugin_settings),

	.parent_offset = (size_t)-1,
};

static const struct setting_parser_info *default_plugin_set_roots[] = {
	&plugin_setting_parser_info,
	NULL
};

static const struct setting_parser_info **plugin_set_roots =
	default_plugin_set_roots;

static struct plugin_settings *plugin_settings_read(void)
{
	const char *error;

	if (master_service_settings_read_simple(
		master_service, plugin_set_roots, &error) < 0)
		i_fatal("Error reading configuration: %s", error);

	return (struct plugin_settings *)
		master_service_settings_get_others(master_service)[0];
}

static const char *
plugin_settings_get(const struct plugin_settings *set, const char *identifier)
{
	const char *const *envs;
	unsigned int i, count;

	if ( !array_is_created(&set->plugin_envs) )
		return NULL;

	envs = array_get(&set->plugin_envs, &count);
	for ( i = 0; i < count; i += 2 ) {
		if ( strcmp(envs[i], identifier) == 0 )
			return envs[i+1];
	}
	return NULL;
}

/*
 * Sieve environment
 */

static const char *sieve_get_setting(void *context, const char *identifier)
{
	const struct plugin_settings *set = context;

	return plugin_settings_get(set, identifier);
}

static const struct sieve_callbacks sieve_callbacks = {
	NULL,
	sieve_get_setting
};

/*
 * Capability dumping
 */

void managesieve_capabilities_dump(void)
{
	const struct plugin_settings *global_plugin_settings;
	struct sieve_environment svenv;
	struct sieve_instance *svinst;
	const char *notify_cap;

	/* Read plugin settings */

	global_plugin_settings = plugin_settings_read();

	/* Initialize Sieve engine */

	memset((void*)&svenv, 0, sizeof(svenv));
	svenv.home_dir = "/tmp";

	svinst = sieve_init(&svenv, &sieve_callbacks,
			    (void *) global_plugin_settings, FALSE);

	/* Dump capabilities */

	notify_cap = sieve_get_capabilities(svinst, "notify");

	if (notify_cap == NULL)
		printf("SIEVE: %s\n", sieve_get_capabilities(svinst, NULL));
	else {
		printf("SIEVE: %s, NOTIFY: %s\n",
		       sieve_get_capabilities(svinst, NULL),
		       sieve_get_capabilities(svinst, "notify"));
	}

	sieve_deinit(&svinst);
}