dovecot-2.1: Moved autocreate plugin functionality into lib-stor...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Dec 2 16:22:42 EET 2011
details: http://hg.dovecot.org/dovecot-2.1/rev/ee783a878120
changeset: 13793:ee783a878120
user: Timo Sirainen <tss at iki.fi>
date: Fri Dec 02 16:22:31 2011 +0200
description:
Moved autocreate plugin functionality into lib-storage.
The autocreate plugin is still used for backwards compatibility.
Mailboxes can be configured like:
mailbox Sent {
auto = subscribe
}
mailbox Spam {
auto = create
}
diffstat:
src/config/settings-get.pl | 1 +
src/lib-storage/mail-storage-private.h | 2 +
src/lib-storage/mail-storage-settings.c | 48 ++
src/lib-storage/mail-storage-settings.h | 12 +
src/lib-storage/mail-storage.c | 77 +++-
src/lib-storage/mailbox-list-iter.c | 270 ++++++++++++++++-
src/lib-storage/mailbox-list-private.h | 1 +
src/plugins/autocreate/autocreate-plugin.c | 473 ++--------------------------
8 files changed, 434 insertions(+), 450 deletions(-)
diffs (truncated from 1111 to 300 lines):
diff -r b48fb6a08389 -r ee783a878120 src/config/settings-get.pl
--- a/src/config/settings-get.pl Fri Dec 02 14:49:08 2011 +0200
+++ b/src/config/settings-get.pl Fri Dec 02 16:22:31 2011 +0200
@@ -8,6 +8,7 @@
print '#include "file-lock.h"'."\n";
print '#include "fsync-mode.h"'."\n";
print '#include "hash-format.h"'."\n";
+print '#include "unichar.h"'."\n";
print '#include "settings-parser.h"'."\n";
print '#include "all-settings.h"'."\n";
print '#include <stddef.h>'."\n";
diff -r b48fb6a08389 -r ee783a878120 src/lib-storage/mail-storage-private.h
--- a/src/lib-storage/mail-storage-private.h Fri Dec 02 14:49:08 2011 +0200
+++ b/src/lib-storage/mail-storage-private.h Fri Dec 02 16:22:31 2011 +0200
@@ -226,6 +226,8 @@
/* default vfuncs for new struct mails. */
const struct mail_vfuncs *mail_vfuncs;
+ /* Mailbox settings, or NULL if defaults */
+ const struct mailbox_settings *set;
/* If non-zero, fail mailbox_open() with this error. mailbox_alloc()
can set this to force open to fail. */
diff -r b48fb6a08389 -r ee783a878120 src/lib-storage/mail-storage-settings.c
--- a/src/lib-storage/mail-storage-settings.c Fri Dec 02 14:49:08 2011 +0200
+++ b/src/lib-storage/mail-storage-settings.c Fri Dec 02 16:22:31 2011 +0200
@@ -4,6 +4,7 @@
#include "array.h"
#include "hash-format.h"
#include "var-expand.h"
+#include "unichar.h"
#include "settings-parser.h"
#include "mail-index.h"
#include "mail-user.h"
@@ -15,6 +16,7 @@
static bool mail_storage_settings_check(void *_set, pool_t pool, const char **error_r);
static bool namespace_settings_check(void *_set, pool_t pool, const char **error_r);
+static bool mailbox_settings_check(void *_set, pool_t pool, const char **error_r);
static bool mail_user_settings_check(void *_set, pool_t pool, const char **error_r);
#undef DEF
@@ -142,6 +144,37 @@
};
#undef DEF
+#define DEF(type, name) \
+ { type, #name, offsetof(struct mailbox_settings, name), NULL }
+
+static const struct setting_define mailbox_setting_defines[] = {
+ DEF(SET_STR, name),
+ { SET_ENUM, "auto", offsetof(struct mailbox_settings, autocreate), NULL } ,
+
+ SETTING_DEFINE_LIST_END
+};
+
+const struct mailbox_settings mailbox_default_settings = {
+ .name = "",
+ .autocreate = MAILBOX_SET_AUTO_NO":"
+ MAILBOX_SET_AUTO_CREATE":"
+ MAILBOX_SET_AUTO_SUBSCRIBE
+};
+
+const struct setting_parser_info mailbox_setting_parser_info = {
+ .defines = mailbox_setting_defines,
+ .defaults = &mailbox_default_settings,
+
+ .type_offset = offsetof(struct mailbox_settings, name),
+ .struct_size = sizeof(struct mailbox_settings),
+
+ .parent_offset = (size_t)-1,
+ .parent = &mail_user_setting_parser_info,
+
+ .check_func = mailbox_settings_check
+};
+
+#undef DEF
#undef DEFLIST_UNIQUE
#define DEF(type, name) \
{ type, #name, offsetof(struct mail_user_settings, name), NULL }
@@ -173,6 +206,7 @@
DEF(SET_STR, mail_log_prefix),
DEFLIST_UNIQUE(namespaces, "namespace", &mail_namespace_setting_parser_info),
+ DEFLIST_UNIQUE(mailboxes, "mailbox", &mailbox_setting_parser_info),
{ SET_STRLIST, "plugin", offsetof(struct mail_user_settings, plugin_envs), NULL },
SETTING_DEFINE_LIST_END
@@ -202,6 +236,7 @@
.mail_log_prefix = "%s(%u): ",
.namespaces = ARRAY_INIT,
+ .mailboxes = ARRAY_INIT,
.plugin_envs = ARRAY_INIT
};
@@ -425,6 +460,19 @@
return TRUE;
}
+static bool mailbox_settings_check(void *_set, pool_t pool ATTR_UNUSED,
+ const char **error_r)
+{
+ struct mailbox_settings *set = _set;
+
+ if (!uni_utf8_str_is_valid(set->name)) {
+ *error_r = t_strdup_printf("mailbox %s: name isn't valid UTF-8",
+ set->name);
+ return FALSE;
+ }
+ return TRUE;
+}
+
static bool mail_user_settings_check(void *_set, pool_t pool ATTR_UNUSED,
const char **error_r ATTR_UNUSED)
{
diff -r b48fb6a08389 -r ee783a878120 src/lib-storage/mail-storage-settings.h
--- a/src/lib-storage/mail-storage-settings.h Fri Dec 02 14:49:08 2011 +0200
+++ b/src/lib-storage/mail-storage-settings.h Fri Dec 02 16:22:31 2011 +0200
@@ -55,6 +55,16 @@
struct mail_user_settings *user_set;
};
+/* <settings checks> */
+#define MAILBOX_SET_AUTO_NO "no"
+#define MAILBOX_SET_AUTO_CREATE "create"
+#define MAILBOX_SET_AUTO_SUBSCRIBE "subscribe"
+/* </settings checks> */
+struct mailbox_settings {
+ const char *name;
+ const char *autocreate;
+};
+
struct mail_user_settings {
const char *base_dir;
const char *auth_socket_path;
@@ -77,6 +87,7 @@
const char *mail_log_prefix;
ARRAY_DEFINE(namespaces, struct mail_namespace_settings *);
+ ARRAY_DEFINE(mailboxes, struct mailbox_settings *);
ARRAY_DEFINE(plugin_envs, const char *);
};
@@ -84,6 +95,7 @@
extern const struct setting_parser_info mail_namespace_setting_parser_info;
extern const struct setting_parser_info mail_storage_setting_parser_info;
extern const struct mail_namespace_settings mail_namespace_default_settings;
+extern const struct mailbox_settings mailbox_default_settings;
const void *
mail_user_set_get_driver_settings(const struct setting_parser_info *info,
diff -r b48fb6a08389 -r ee783a878120 src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c Fri Dec 02 14:49:08 2011 +0200
+++ b/src/lib-storage/mail-storage.c Fri Dec 02 16:22:31 2011 +0200
@@ -602,6 +602,18 @@
return TRUE;
}
+static struct mailbox_settings *
+mailbox_settings_find(struct mail_user *user, const char *vname)
+{
+ struct mailbox_settings *const *box_set;
+
+ array_foreach(&user->set->mailboxes, box_set) {
+ if (strcmp((*box_set)->name, vname) == 0)
+ return *box_set;
+ }
+ return NULL;
+}
+
struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *vname,
enum mailbox_flags flags)
{
@@ -628,6 +640,7 @@
T_BEGIN {
box = storage->v.mailbox_alloc(storage, new_list, vname, flags);
+ box->set = mailbox_settings_find(storage->user, vname);
hook_mailbox_allocated(box);
} T_END;
@@ -704,6 +717,14 @@
return FALSE;
}
+static bool mailbox_is_autocreated(struct mailbox *box)
+{
+ if (box->inbox_user)
+ return TRUE;
+ return box->set != NULL &&
+ strcmp(box->set->autocreate, MAILBOX_SET_AUTO_NO) != 0;
+}
+
int mailbox_exists(struct mailbox *box, bool auto_boxes,
enum mailbox_existence *existence_r)
{
@@ -732,8 +753,7 @@
return 0;
}
- if (strcmp(box->name, "INBOX") == 0 && box->inbox_user && auto_boxes) {
- /* INBOX always exists */
+ if (auto_boxes && box->set != NULL && mailbox_is_autocreated(box)) {
*existence_r = MAILBOX_EXISTENCE_SELECT;
return 0;
}
@@ -788,6 +808,47 @@
return 0;
}
+static void mailbox_autocreate(struct mailbox *box)
+{
+ const char *errstr;
+ enum mail_error error;
+
+ if (mailbox_create(box, NULL, FALSE) < 0) {
+ errstr = mailbox_get_last_error(box, &error);
+ if (error != MAIL_ERROR_NOTFOUND && !box->inbox_user) {
+ mail_storage_set_critical(box->storage,
+ "Failed to autocreate mailbox %s: %s",
+ box->vname, errstr);
+ }
+ } else if (box->set != NULL &&
+ strcmp(box->set->autocreate,
+ MAILBOX_SET_AUTO_SUBSCRIBE) == 0) {
+ if (mailbox_set_subscribed(box, TRUE) < 0) {
+ mail_storage_set_critical(box->storage,
+ "Failed to autosubscribe to mailbox %s: %s",
+ box->vname, mailbox_get_last_error(box, NULL));
+ }
+ }
+}
+
+static int mailbox_autocreate_and_reopen(struct mailbox *box)
+{
+ int ret;
+
+ mailbox_autocreate(box);
+ mailbox_close(box);
+
+ ret = box->v.open(box);
+ if (ret < 0 && box->inbox_user &&
+ !box->storage->user->inbox_open_error_logged) {
+ box->storage->user->inbox_open_error_logged = TRUE;
+ mail_storage_set_critical(box->storage,
+ "Opening INBOX failed: %s",
+ mailbox_get_last_error(box, NULL));
+ }
+ return ret;
+}
+
static int mailbox_open_full(struct mailbox *box, struct istream *input)
{
int ret;
@@ -832,16 +893,8 @@
} T_END;
if (ret < 0 && box->storage->error == MAIL_ERROR_NOTFOUND &&
- box->input == NULL && box->inbox_user) T_BEGIN {
- /* INBOX should always exist. try to create it and retry. */
- (void)mailbox_create(box, NULL, FALSE);
- mailbox_close(box);
- ret = box->v.open(box);
- if (ret < 0 && !box->storage->user->inbox_open_error_logged) {
- box->storage->user->inbox_open_error_logged = TRUE;
- i_error("Opening INBOX failed: %s",
- mailbox_get_last_error(box, NULL));
- }
+ box->input == NULL && mailbox_is_autocreated(box)) T_BEGIN {
+ ret = mailbox_autocreate_and_reopen(box);
} T_END;
if (ret < 0) {
diff -r b48fb6a08389 -r ee783a878120 src/lib-storage/mailbox-list-iter.c
--- a/src/lib-storage/mailbox-list-iter.c Fri Dec 02 14:49:08 2011 +0200
+++ b/src/lib-storage/mailbox-list-iter.c Fri Dec 02 16:22:31 2011 +0200
@@ -1,10 +1,35 @@
/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */
#include "lib.h"
+#include "array.h"
#include "imap-match.h"
#include "mailbox-tree.h"
#include "mailbox-list-private.h"
+enum autocreate_match_result {
+ /* list contains the mailbox */
+ AUTOCREATE_MATCH_RESULT_YES = 0x01,
+ /* list contains children of the mailbox */
+ AUTOCREATE_MATCH_RESULT_CHILDREN = 0x02,
+ /* list contains parents of the mailbox */
+ AUTOCREATE_MATCH_RESULT_PARENT = 0x04
+};
+
+struct autocreate_box {
+ const char *name;
+ enum mailbox_info_flags flags;
+ bool child_listed;
+};
More information about the dovecot-cvs
mailing list