virtual-config.c revision 61cf001f1944d92eb25f113ba4c08985d6e30d53
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2008-2017 Dovecot authors, see the included COPYING file */
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainenvirtual_search_args_parse(const string_t *rule, const char **error_r)
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen input = i_stream_create_from_data(str_data(rule), str_len(rule));
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen imap_parser = imap_parser_create(input, NULL, (size_t)-1);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen ret = imap_parser_finish_line(imap_parser, 0, 0, &args);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen *error_r = t_strdup(imap_parser_get_error(imap_parser, NULL));
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen if (mail_search_build(mail_search_register_get_imap(),
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainenvirtual_config_add_rule(struct virtual_parse_context *ctx, const char **error_r)
88f73e2ed3e99417255c90890fa46e11e6378c9dTimo Sirainen unsigned int i, count;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (ctx->rule_idx == array_count(&ctx->mbox->backend_boxes)) {
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen crc32_str_more(ctx->mbox->search_args_crc32, str_c(ctx->rule));
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen search_args = virtual_search_args_parse(ctx->rule, error_r);
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen *error_r = t_strconcat("Previous search rule is invalid: ",
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen /* update at all the mailboxes that were introduced since the previous
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen bboxes = array_get(&ctx->mbox->backend_boxes, &count);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen ctx->rule_idx = array_count(&ctx->mbox->backend_boxes);
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainenvirtual_config_parse_line(struct virtual_parse_context *ctx, const char *line,
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen const char **error_r)
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen struct mail_user *user = ctx->mbox->storage->storage.user;
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk const char *p;
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen /* continues the previous search rule */
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (ctx->rule_idx == array_count(&ctx->mbox->backend_boxes)) {
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen /* if there is no rule yet, it means we want the previous mailboxes
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen to use the rule that comes later */
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen if (virtual_config_add_rule(ctx, error_r) < 0)
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen *error_r = t_strdup_printf("Mailbox name not UTF-8: %s",
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen /* new mailbox. the search args are added to it later. */
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen bbox = p_new(ctx->pool, struct virtual_backend_box, 1);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen /* save messages here */
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen /* [+-!]/metadata entry:value */
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen *error_r = "':' separator missing between metadata entry name and value";
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen bbox->metadata_entry = p_strdup_until(ctx->pool, bbox->name, p++);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen if (!imap_metadata_verify_entry_name(bbox->metadata_entry, error_r))
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen bbox->glob = imap_match_init(ctx->pool, bbox->name, TRUE, ctx->sep);
747e77e3ab073a8e9e69c7a3e71b4593c5655d03Timo Sirainen /* now that the prefix characters have been processed,
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen find the namespace */
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen bbox->ns = strcasecmp(bbox->name, "INBOX") == 0 ?
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen mail_namespace_find(user->namespaces, bbox->name);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen *error_r = t_strdup_printf("Namespace not found for %s",
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen if (strcmp(bbox->name, ctx->mbox->box.vname) == 0) {
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen *error_r = "Virtual mailbox can't point to itself";
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen array_append(&ctx->mbox->backend_boxes, &bbox, 1);
f3d506e525a720f214020ca0f989a1966b30edaeTimo Sirainenvirtual_mailbox_get_list_patterns(struct virtual_parse_context *ctx)
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen unsigned int i, count;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen bboxes = array_get_modifiable(&mbox->backend_boxes, &count);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen p_array_init(&mbox->list_include_patterns, ctx->pool, count);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen p_array_init(&mbox->list_exclude_patterns, ctx->pool, count);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen for (i = 0; i < count; i++) {
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainenseparate_wildcard_mailboxes(struct virtual_mailbox *mbox,
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen ARRAY_TYPE(virtual_backend_box) *wildcard_boxes,
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen ARRAY_TYPE(virtual_backend_box) *metadata_boxes)
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen unsigned int i, count;
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen bboxes = array_get_modifiable(&mbox->backend_boxes, &count);
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen t_array_init(wildcard_boxes, I_MIN(16, count));
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen for (i = 0; i < count;) {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen bboxes = array_get_modifiable(&mbox->backend_boxes,
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenstatic void virtual_config_copy_expanded(struct virtual_parse_context *ctx,
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen bbox = p_new(ctx->pool, struct virtual_backend_box, 1);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen array_append(&ctx->mbox->backend_boxes, &bbox, 1);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenstatic bool virtual_ns_match(struct mail_namespace *config_ns,
return TRUE;
return TRUE;
return TRUE;
return FALSE;
unsigned int *idx_r)
unsigned int i, count;
for (i = 0; i < count; i++) {
*idx_r = i;
return TRUE;
*idx_r = i;
return TRUE;
return FALSE;
const char **error_r)
int ret;
if (ret < 0)
if (ret > 0)
return ret;
const char **error_r)
unsigned int i, count;
if (count == 0)
for (i = 0; i < count; i++) {
return ret;
const char **error_r)
const char **patterns;
unsigned int i, j, count;
int ret = 0;
if (count == 0) {
for (i = 0; i < count; i++)
if (ret < 0)
if (ret > 0) {
for (i = 0; i < count; i++)
unsigned int i, count;
for (i = 0; i < count; i++) {
unsigned int linenum = 0;
linenum++;
if (ret < 0) {
if (ret == 0) {
if (ret < 0) {
if (ret < 0)
if (ret == 0)
return ret;
unsigned int i, count;
for (i = 0; i < count; i++) {