mailbox-list.c revision 220e21750948941dc6e33b8f11b552fa21d7f81e
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (C) 2006 Timo Sirainen */
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen
46552a931924c2d743f045e95b08c3ce6beda91aTimo Sirainen#include "lib.h"
3cb26db7f4756b71ba06c6e4950fa4f8ce7fad66Timo Sirainen#include "array.h"
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen#include "ioloop.h"
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen#include "mailbox-list-private.h"
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen#include <time.h>
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen#include <dirent.h>
45155bb1250cf5a120278f349465aded513a100fTimo Sirainen
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen/* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and
0af9ef2e9bb71a426bba236e74ceec30be699fb7Timo Sirainen then start renaming them to larger names from end to beginning, which
e3a838c80f54f024115fade93c6c87a0998f1fabTimo Sirainen eventually would start causing the failures when trying to use too
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen long mailbox names. */
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen#define MAILBOX_MAX_HIERARCHY_LEVELS 20
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen#define MAILBOX_MAX_HIERARCHY_NAME_LENGTH 200
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen
3cb26db7f4756b71ba06c6e4950fa4f8ce7fad66Timo Sirainen/* Message to show to users when critical error occurs */
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen#define CRITICAL_MSG \
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen "Internal error occurred. Refer to server log for more information."
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen#define CRITICAL_MSG_STAMP CRITICAL_MSG " [%Y-%m-%d %H:%M:%S]"
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainenunsigned int mailbox_list_module_id = 0;
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainenvoid (*hook_mailbox_list_created)(struct mailbox_list *list);
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainenstatic ARRAY_DEFINE(mailbox_list_drivers, const struct mailbox_list *);
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainenstatic bool mailbox_list_driver_find(const char *name, unsigned int *idx_r)
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen{
9508ac436fff0e1dcea975855c139cd251deb703Timo Sirainen const struct mailbox_list *const *drivers;
ddbdc644a15f56f4b43596f1b8c0fc196c101445Timo Sirainen unsigned int i, count;
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen drivers = array_get(&mailbox_list_drivers, &count);
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen for (i = 0; i < count; i++) {
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen if (strcasecmp(drivers[i]->name, name) == 0) {
493123e38ca1f27b07ac30dcbc59663c5fcdcba2Timo Sirainen *idx_r = i;
ddbdc644a15f56f4b43596f1b8c0fc196c101445Timo Sirainen return TRUE;
ddbdc644a15f56f4b43596f1b8c0fc196c101445Timo Sirainen }
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen }
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen return FALSE;
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen}
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen
ddbdc644a15f56f4b43596f1b8c0fc196c101445Timo Sirainenvoid mailbox_list_register(const struct mailbox_list *list)
ddbdc644a15f56f4b43596f1b8c0fc196c101445Timo Sirainen{
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen if (!array_is_created(&mailbox_list_drivers))
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen i_array_init(&mailbox_list_drivers, 4);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen else {
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen unsigned int idx;
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen if (mailbox_list_driver_find(list->name, &idx)) {
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen i_fatal("mailbox_list_register(%s): duplicate driver",
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen list->name);
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen }
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen }
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi array_append(&mailbox_list_drivers, &list, 1);
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi}
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomivoid mailbox_list_unregister(const struct mailbox_list *list)
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi{
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi unsigned int idx;
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi if (!mailbox_list_driver_find(list->name, &idx)) {
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi i_fatal("mailbox_list_unregister(%s): unknown driver",
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi list->name);
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi }
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi array_delete(&mailbox_list_drivers, idx, 1);
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi if (array_count(&mailbox_list_drivers) == 0)
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi array_free(&mailbox_list_drivers);
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi}
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainenint mailbox_list_init(const char *driver,
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen const struct mailbox_list_settings *set,
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen enum mailbox_list_flags flags,
2c5c293940fd6c7e020e1d58dae77a9d01f9059bTimo Sirainen mailbox_list_is_mailbox_t *callback, void *context,
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen struct mailbox_list **list_r, const char **error_r)
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen{
3bc9d91f987261e989aa653fd412b0e8095e4810Timo Sirainen const struct mailbox_list *const *class_p;
3bc9d91f987261e989aa653fd412b0e8095e4810Timo Sirainen struct mailbox_list *list;
3bc9d91f987261e989aa653fd412b0e8095e4810Timo Sirainen unsigned int idx;
3bc9d91f987261e989aa653fd412b0e8095e4810Timo Sirainen
3bc9d91f987261e989aa653fd412b0e8095e4810Timo Sirainen if (!mailbox_list_driver_find(driver, &idx)) {
3bc9d91f987261e989aa653fd412b0e8095e4810Timo Sirainen *error_r = "Unknown mailbox list driver";
41783dcf1bcd7118440c9c40a691a09fb98a9460Timo Sirainen return -1;
41783dcf1bcd7118440c9c40a691a09fb98a9460Timo Sirainen }
41783dcf1bcd7118440c9c40a691a09fb98a9460Timo Sirainen
41783dcf1bcd7118440c9c40a691a09fb98a9460Timo Sirainen i_assert(*set->root_dir != '\0');
5324117274df8564eeaebe369cb1eca76edb3165Timo Sirainen i_assert(*set->subscription_fname != '\0');
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen class_p = array_idx(&mailbox_list_drivers, idx);
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen list = (*class_p)->v.alloc();
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen list->flags = flags;
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen list->callback = callback;
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen list->context = context;
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen
52fe791133ad838c3aca3f1c88f96aab755950f8Timo Sirainen /* copy settings */
52fe791133ad838c3aca3f1c88f96aab755950f8Timo Sirainen list->set.root_dir = p_strdup(list->pool, set->root_dir);
52fe791133ad838c3aca3f1c88f96aab755950f8Timo Sirainen list->set.index_dir = set->index_dir == NULL ||
52fe791133ad838c3aca3f1c88f96aab755950f8Timo Sirainen strcmp(set->index_dir, set->root_dir) == 0 ? NULL :
52fe791133ad838c3aca3f1c88f96aab755950f8Timo Sirainen p_strdup(list->pool, set->index_dir);
52fe791133ad838c3aca3f1c88f96aab755950f8Timo Sirainen list->set.control_dir = set->control_dir == NULL ||
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen strcmp(set->control_dir, set->root_dir) == 0 ? NULL :
686ad6d723004b807fd558f3ef9d1f88afa7e127Timo Sirainen p_strdup(list->pool, set->control_dir);
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen
686ad6d723004b807fd558f3ef9d1f88afa7e127Timo Sirainen list->set.inbox_path = p_strdup(list->pool, set->inbox_path);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen list->set.subscription_fname =
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen p_strdup(list->pool, set->subscription_fname);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen list->set.maildir_name = p_strdup(list->pool, set->maildir_name);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen if ((flags & MAILBOX_LIST_FLAG_DEBUG) != 0) {
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen i_info("%s: root=%s, index=%s, control=%s, inbox=%s",
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen driver, list->set.root_dir,
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen list->set.index_dir == NULL ? "" : list->set.index_dir,
26681e71837ebbb3eb92455ec4e3cadefa710f82Timo Sirainen list->set.control_dir == NULL ?
26681e71837ebbb3eb92455ec4e3cadefa710f82Timo Sirainen "" : list->set.control_dir,
26681e71837ebbb3eb92455ec4e3cadefa710f82Timo Sirainen list->set.inbox_path == NULL ?
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen "" : list->set.inbox_path);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen }
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen array_create(&list->module_contexts, list->pool, sizeof(void *), 5);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen if (hook_mailbox_list_created != NULL)
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen hook_mailbox_list_created(list);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen *list_r = list;
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen return 0;
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen}
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainenvoid mailbox_list_deinit(struct mailbox_list *list)
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen{
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen i_free_and_null(list->error);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen list->v.deinit(list);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen}
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainenconst char *mailbox_list_get_driver_name(struct mailbox_list *list)
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen{
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen return list->name;
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen}
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainenchar mailbox_list_get_hierarchy_sep(struct mailbox_list *list)
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen{
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen return list->hierarchy_sep;
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen}
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen
3cb26db7f4756b71ba06c6e4950fa4f8ce7fad66Timo Sirainenbool mailbox_list_is_valid_mask(struct mailbox_list *list, const char *mask)
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen{
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi return list->v.is_valid_mask(list, mask);
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen}
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenbool mailbox_list_is_valid_existing_name(struct mailbox_list *list,
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen const char *name)
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen{
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen return list->v.is_valid_existing_name(list, name);
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen}
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainenbool mailbox_list_is_valid_create_name(struct mailbox_list *list,
53d564c421ca7292d7b1bd945f86894a34b75370Timo Sirainen const char *name)
3cb26db7f4756b71ba06c6e4950fa4f8ce7fad66Timo Sirainen{
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen return list->v.is_valid_create_name(list, name);
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen}
52fe791133ad838c3aca3f1c88f96aab755950f8Timo Sirainen
52fe791133ad838c3aca3f1c88f96aab755950f8Timo Sirainenconst char *mailbox_list_get_path(struct mailbox_list *list, const char *name,
5324117274df8564eeaebe369cb1eca76edb3165Timo Sirainen enum mailbox_list_path_type type)
5324117274df8564eeaebe369cb1eca76edb3165Timo Sirainen{
5324117274df8564eeaebe369cb1eca76edb3165Timo Sirainen return list->v.get_path(list, name, type);
6d24551e169c0808695db35d7a228f1970a84c75Timo Sirainen}
6d24551e169c0808695db35d7a228f1970a84c75Timo Sirainen
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomiconst char *mailbox_list_get_temp_prefix(struct mailbox_list *list)
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi{
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi return list->v.get_temp_prefix(list);
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi}
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomiint mailbox_list_get_mailbox_name_status(struct mailbox_list *list,
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi const char *name,
53d564c421ca7292d7b1bd945f86894a34b75370Timo Sirainen enum mailbox_name_status *status)
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen{
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi return list->v.get_mailbox_name_status(list, name, status);
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi}
abd4203d97d6db19550fc45d6b6806b2deadb625Aki Tuomi
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainenstruct mailbox_list_iterate_context *
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainenmailbox_list_iter_init(struct mailbox_list *list,
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen const char *ref, const char *mask,
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen enum mailbox_list_iter_flags flags)
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen{
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen return list->v.iter_init(list, ref, mask, flags);
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen}
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainenstruct mailbox_info *
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainenmailbox_list_iter_next(struct mailbox_list_iterate_context *ctx)
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen{
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen return ctx->list->v.iter_next(ctx);
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen}
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainenint mailbox_list_iter_deinit(struct mailbox_list_iterate_context **_ctx)
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen{
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen struct mailbox_list_iterate_context *ctx = *_ctx;
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen *_ctx = NULL;
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen return ctx->list->v.iter_deinit(ctx);
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen}
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainenint mailbox_list_set_subscribed(struct mailbox_list *list,
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen const char *name, bool set)
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen{
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen return list->v.set_subscribed(list, name, set);
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen}
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainenbool mailbox_list_name_is_too_large(const char *name, char sep)
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen{
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen unsigned int levels = 1, level_len = 0;
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen for (; *name != '\0'; name++) {
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen if (*name == sep) {
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen if (level_len > MAILBOX_MAX_HIERARCHY_NAME_LENGTH)
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen return TRUE;
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen levels++;
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen level_len = 0;
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen } else {
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen level_len++;
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen }
be71a9de88d1266597eb8c5e0b6f519d90e14397Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen if (level_len > MAILBOX_MAX_HIERARCHY_NAME_LENGTH)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return TRUE;
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen if (levels > MAILBOX_MAX_HIERARCHY_LEVELS)
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen return TRUE;
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen return FALSE;
2c5c293940fd6c7e020e1d58dae77a9d01f9059bTimo Sirainen}
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainenenum mailbox_list_file_type mailbox_list_get_file_type(const struct dirent *d)
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen{
feb665db52583259a1f42037c6e8a22852aa8889Timo Sirainen enum mailbox_list_file_type type;
9bc0204ec8bda657ce2e96e6ae715e4034f1538bTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#ifdef HAVE_DIRENT_D_TYPE
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen switch (d->d_type) {
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen case DT_UNKNOWN:
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen type = MAILBOX_LIST_FILE_TYPE_UNKNOWN;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen break;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen case DT_REG:
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen type = MAILBOX_LIST_FILE_TYPE_FILE;
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen break;
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen case DT_DIR:
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen type = MAILBOX_LIST_FILE_TYPE_DIR;
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen break;
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen case DT_LNK:
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen type = MAILBOX_LIST_FILE_TYPE_SYMLINK;
27d50b3aa143964143e4bef66c0bfe3c72aea233Timo Sirainen break;
27d50b3aa143964143e4bef66c0bfe3c72aea233Timo Sirainen default:
9c47edf0d1aa8afa6d05dde93e7aa5169059c94aTimo Sirainen type = MAILBOX_LIST_FILE_TYPE_OTHER;
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen break;
9c47edf0d1aa8afa6d05dde93e7aa5169059c94aTimo Sirainen }
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen#else
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen type = MAILBOX_LIST_FILE_TYPE_UNKNOWN;
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen#endif
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen return type;
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen}
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainenconst char *mailbox_list_get_last_error(struct mailbox_list *list,
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen bool *temporary_error_r)
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen{
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen *temporary_error_r = list->temporary_error;
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen return list->error;
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen}
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainenvoid mailbox_list_clear_error(struct mailbox_list *list)
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen{
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen i_free_and_null(list->error);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen list->temporary_error = FALSE;
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen}
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
d229d26d263a57a77eec8fe7cba24fbfd9509966Timo Sirainenvoid mailbox_list_set_error(struct mailbox_list *list, const char *error)
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen{
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen i_free(list->error);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen list->error = i_strdup(error);
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen list->temporary_error = FALSE;
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen}
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainenstatic void mailbox_list_set_internal_error(struct mailbox_list *list)
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen{
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen struct tm *tm;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen char str[256];
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen tm = localtime(&ioloop_time);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen i_free(list->error);
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen list->error =
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen strftime(str, sizeof(str), CRITICAL_MSG_STAMP, tm) > 0 ?
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen i_strdup(str) : i_strdup(CRITICAL_MSG);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen list->temporary_error = TRUE;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainenvoid mailbox_list_set_critical(struct mailbox_list *list, const char *fmt, ...)
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen va_list va;
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen va_start(va, fmt);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen i_error("%s", t_strdup_vprintf(fmt, va));
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen va_end(va);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen /* critical errors may contain sensitive data, so let user
e95dba8921087afebb8a92c592af3b8ca22ae796Timo Sirainen see only "Internal error" with a timestamp to make it
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen easier to look from log files the actual error message. */
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen mailbox_list_set_internal_error(list);
3612ee5c737954d5fb88fd1775aad80f7bf1dc4eTimo Sirainen}
8e50329e2c5e3a199674ae9f6d3dfcddab02487bTimo Sirainen