/src/pigeonhole/src/lib-sieve/sieve-storage-settings.c
Line | Count | Source |
1 | | /* Copyright (c) Pigeonhole authors, see top-level COPYING file */ |
2 | | |
3 | | #include "lib.h" |
4 | | #include "str-sanitize.h" |
5 | | #include "array.h" |
6 | | #include "sort.h" |
7 | | #include "settings.h" |
8 | | #include "settings-parser.h" |
9 | | |
10 | | #include "sieve-script.h" |
11 | | #include "sieve-storage.h" |
12 | | #include "sieve-storage-settings.h" |
13 | | |
14 | | static bool |
15 | | sieve_storage_settings_check(void *_set, pool_t pool, const char **error_r); |
16 | | |
17 | | #undef DEF |
18 | | #define DEF(type, name) SETTING_DEFINE_STRUCT_##type( \ |
19 | | "sieve_"#name, name, \ |
20 | | struct sieve_storage_settings) |
21 | | |
22 | | static const struct setting_filter_array_order sieve_storage_order_precedence = { |
23 | | .info = &sieve_storage_setting_parser_info, |
24 | | .field_name = "sieve_script_precedence", |
25 | | }; |
26 | | |
27 | | static const struct setting_define sieve_storage_setting_defines[] = { |
28 | | DEF(STR, script_storage), |
29 | | DEF(UINT, script_precedence), |
30 | | |
31 | | DEF(STR, script_type), |
32 | | DEF(BOOLLIST, script_cause), |
33 | | DEF(STR, script_driver), |
34 | | DEF(STR, script_name), |
35 | | DEF(STR, script_bin_path), |
36 | | |
37 | | DEF(SIZE, quota_storage_size), |
38 | | DEF(UINT, quota_script_count), |
39 | | |
40 | | { .type = SET_FILTER_ARRAY, .key = "sieve_script", |
41 | | .offset = offsetof(struct sieve_storage_settings, storages), |
42 | | .filter_array_field_name = "sieve_script_storage", |
43 | | .filter_array_order = &sieve_storage_order_precedence }, |
44 | | |
45 | | SETTING_DEFINE_LIST_END, |
46 | | }; |
47 | | |
48 | | static const struct sieve_storage_settings sieve_storage_default_settings = { |
49 | | .script_storage = "", |
50 | | .script_precedence = UINT_MAX, |
51 | | |
52 | | .script_type = SIEVE_STORAGE_TYPE_PERSONAL, |
53 | | .script_cause = ARRAY_INIT, |
54 | | |
55 | | .script_driver = "file", |
56 | | .script_name = "", |
57 | | .script_bin_path = "", |
58 | | |
59 | | .quota_storage_size = SET_SIZE_UNLIMITED, |
60 | | .quota_script_count = SET_UINT_UNLIMITED, |
61 | | |
62 | | .storages = ARRAY_INIT, |
63 | | }; |
64 | | |
65 | | const struct setting_parser_info sieve_storage_setting_parser_info = { |
66 | | .name = "sieve_storage", |
67 | | |
68 | | .defines = sieve_storage_setting_defines, |
69 | | .defaults = &sieve_storage_default_settings, |
70 | | |
71 | | .struct_size = sizeof(struct sieve_storage_settings), |
72 | | |
73 | | .pool_offset1 = 1 + offsetof(struct sieve_storage_settings, pool), |
74 | | |
75 | | .check_func = sieve_storage_settings_check, |
76 | | }; |
77 | | |
78 | | /* <settings checks> */ |
79 | | static bool |
80 | | sieve_storage_settings_check(void *_set, pool_t pool ATTR_UNUSED, |
81 | | const char **error_r) |
82 | 0 | { |
83 | 0 | struct sieve_storage_settings *set = _set; |
84 | |
|
85 | 0 | if (*set->script_storage != '\0' && |
86 | 0 | !sieve_storage_name_is_valid(set->script_storage)) { |
87 | 0 | *error_r = t_strdup_printf( |
88 | 0 | "Invalid script storage name '%s'", |
89 | 0 | str_sanitize(set->script_storage, 128)); |
90 | 0 | return FALSE; |
91 | 0 | } |
92 | 0 | if (*set->script_name != '\0' && |
93 | 0 | !sieve_script_name_is_valid(set->script_name)) { |
94 | 0 | *error_r = t_strdup_printf( |
95 | 0 | "Invalid script name '%s'", |
96 | 0 | str_sanitize(set->script_name, 128)); |
97 | 0 | return FALSE; |
98 | 0 | } |
99 | | |
100 | 0 | if (set->quota_storage_size == 0) { |
101 | 0 | *error_r = "quota_storage_size must not be 0"; |
102 | 0 | return FALSE; |
103 | 0 | } |
104 | 0 | if (set->quota_script_count == 0) { |
105 | 0 | *error_r = "quota_script_count must not be 0"; |
106 | 0 | return FALSE; |
107 | 0 | } |
108 | | |
109 | 0 | if (array_is_created(&set->script_cause)) |
110 | 0 | array_sort(&set->script_cause, i_strcmp_p); |
111 | |
|
112 | 0 | return TRUE; |
113 | 0 | } |
114 | | /* </settings checks> */ |
115 | | |
116 | | bool sieve_storage_settings_match_script_type( |
117 | | const struct sieve_storage_settings *set, const char *type) |
118 | 0 | { |
119 | 0 | if (strcasecmp(type, SIEVE_STORAGE_TYPE_ANY) == 0) |
120 | 0 | return TRUE; |
121 | 0 | if (strcasecmp(type, set->script_type) == 0) |
122 | 0 | return TRUE; |
123 | 0 | return FALSE; |
124 | 0 | } |
125 | | |
126 | | bool sieve_storage_settings_match_script_cause( |
127 | | const struct sieve_storage_settings *set, const char *cause) |
128 | 0 | { |
129 | 0 | if (strcasecmp(cause, SIEVE_SCRIPT_CAUSE_ANY) == 0) { |
130 | | /* Any cause will match */ |
131 | 0 | return TRUE; |
132 | 0 | } |
133 | 0 | if (!array_is_created(&set->script_cause)) { |
134 | | /* Causes are not configured for this storage */ |
135 | 0 | if (strcasecmp(set->script_type, |
136 | 0 | SIEVE_STORAGE_TYPE_PERSONAL) == 0) { |
137 | | /* For personal storages the default is to match any |
138 | | cause. */ |
139 | 0 | return TRUE; |
140 | 0 | } |
141 | 0 | if (strcasecmp(cause, SIEVE_SCRIPT_CAUSE_DELIVERY) == 0) { |
142 | | /* The default cause is delivery */ |
143 | 0 | return TRUE; |
144 | 0 | } |
145 | 0 | return FALSE; |
146 | 0 | } |
147 | | |
148 | | /* Causes are configured for this storage: perform lookup */ |
149 | | |
150 | 0 | unsigned int set_cause_count; |
151 | 0 | const char *const *set_cause; |
152 | |
|
153 | 0 | set_cause = array_get(&set->script_cause, &set_cause_count); |
154 | 0 | return (i_bsearch(cause, set_cause, set_cause_count, |
155 | | sizeof(const char *), search_strcasecmp) != NULL); |
156 | 0 | } |