dovecot-2.0: quota: Avoid calling i_fatal() on initialization er...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Sep 21 20:05:23 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/3780caa2a6f2
changeset: 12150:3780caa2a6f2
user: Timo Sirainen <tss at iki.fi>
date: Tue Sep 21 18:05:13 2010 +0100
description:
quota: Avoid calling i_fatal() on initialization errors, plus some other fixes.
diffstat:
src/plugins/quota/quota-storage.c | 20 ++-
src/plugins/quota/quota.c | 288 ++++++++++++++++++++++++-----------------
src/plugins/quota/quota.h | 16 +-
3 files changed, 192 insertions(+), 132 deletions(-)
diffs (truncated from 436 to 300 lines):
diff -r 7dd6ff192718 -r 3780caa2a6f2 src/plugins/quota/quota-storage.c
--- a/src/plugins/quota/quota-storage.c Tue Sep 21 18:04:30 2010 +0100
+++ b/src/plugins/quota/quota-storage.c Tue Sep 21 18:05:13 2010 +0100
@@ -454,14 +454,28 @@
struct mail_user_vfuncs *v = user->vlast;
struct quota_user *quser;
struct quota_settings *set;
+ struct quota *quota;
+ const char *error;
+ int ret;
- set = quota_user_read_settings(user);
- if (set != NULL) {
+ if ((ret = quota_user_read_settings(user, &set, &error)) > 0) {
+ if (quota_init(set, user, "a, &error) < 0) {
+ quota_settings_deinit(&set);
+ ret = -1;
+ }
+ }
+
+ if (ret < 0) {
+ user->error = p_strdup_printf(user->pool,
+ "Failed to initialize quota: %s", error);
+ return;
+ }
+ if (ret > 0) {
quser = p_new(user->pool, struct quota_user, 1);
quser->module_ctx.super = *v;
user->vlast = &quser->module_ctx.super;
v->deinit = quota_user_deinit;
- quser->quota = quota_init(set, user);
+ quser->quota = quota;
MODULE_CONTEXT_SET(user, quota_user_module, quser);
} else if (user->mail_debug) {
diff -r 7dd6ff192718 -r 3780caa2a6f2 src/plugins/quota/quota.c
--- a/src/plugins/quota/quota.c Tue Sep 21 18:04:30 2010 +0100
+++ b/src/plugins/quota/quota.c Tue Sep 21 18:05:13 2010 +0100
@@ -45,96 +45,6 @@
static int quota_default_test_alloc(struct quota_transaction_context *ctx,
uoff_t size, bool *too_large_r);
-static void quota_root_add_rules(struct mail_user *user, const char *root_name,
- struct quota_root_settings *root_set)
-{
- const char *rule_name, *rule, *error;
- unsigned int i;
-
- rule_name = t_strconcat(root_name, "_rule", NULL);
- for (i = 2;; i++) {
- rule = mail_user_plugin_getenv(user, rule_name);
- if (rule == NULL)
- break;
-
- if (quota_root_add_rule(root_set, rule, &error) < 0) {
- i_fatal("Quota root %s: Invalid rule %s: %s",
- root_name, rule, error);
- }
- rule_name = t_strdup_printf("%s_rule%d", root_name, i);
- }
-}
-
-static void
-quota_root_add_warning_rules(struct mail_user *user, const char *root_name,
- struct quota_root_settings *root_set)
-{
- const char *rule_name, *rule, *error;
- unsigned int i;
-
- rule_name = t_strconcat(root_name, "_warning", NULL);
- for (i = 2;; i++) {
- rule = mail_user_plugin_getenv(user, rule_name);
- if (rule == NULL)
- break;
-
- if (quota_root_add_warning_rule(root_set, rule, &error) < 0) {
- i_fatal("Quota root %s: Invalid warning rule: %s",
- root_name, rule);
- }
- rule_name = t_strdup_printf("%s_warning%d", root_name, i);
- }
-}
-
-struct quota_settings *quota_user_read_settings(struct mail_user *user)
-{
- struct quota_settings *quota_set;
- struct quota_root_settings *root_set;
- char root_name[6 + MAX_INT_STRLEN];
- const char *env;
- unsigned int i;
- pool_t pool;
-
- pool = pool_alloconly_create("quota settings", 2048);
- quota_set = p_new(pool, struct quota_settings, 1);
- quota_set->pool = pool;
- quota_set->test_alloc = quota_default_test_alloc;
- quota_set->debug = user->mail_debug;
- quota_set->quota_exceeded_msg =
- mail_user_plugin_getenv(user, "quota_exceeded_message");
- if (quota_set->quota_exceeded_msg == NULL)
- quota_set->quota_exceeded_msg = DEFAULT_QUOTA_EXCEEDED_MSG;
-
- p_array_init("a_set->root_sets, pool, 4);
- i_strocpy(root_name, "quota", sizeof(root_name));
- for (i = 2;; i++) {
- env = mail_user_plugin_getenv(user, root_name);
- if (env == NULL)
- break;
-
- root_set = quota_root_settings_init(quota_set, env);
- if (root_set == NULL) {
- i_fatal("Couldn't create quota root %s: %s",
- root_name, env);
- }
- quota_root_add_rules(user, root_name, root_set);
- quota_root_add_warning_rules(user, root_name, root_set);
-
- i_snprintf(root_name, sizeof(root_name), "quota%d", i);
- }
-
- return quota_set;
-}
-
-void quota_settings_deinit(struct quota_settings **_quota_set)
-{
- struct quota_settings *quota_set = *_quota_set;
-
- *_quota_set = NULL;
-
- pool_unref("a_set->pool);
-}
-
static const struct quota_backend *quota_backend_find(const char *name)
{
unsigned int i;
@@ -147,8 +57,57 @@
return NULL;
}
-struct quota_root_settings *
-quota_root_settings_init(struct quota_settings *quota_set, const char *root_def)
+static int quota_root_add_rules(struct mail_user *user, const char *root_name,
+ struct quota_root_settings *root_set,
+ const char **error_r)
+{
+ const char *rule_name, *rule, *error;
+ unsigned int i;
+
+ rule_name = t_strconcat(root_name, "_rule", NULL);
+ for (i = 2;; i++) {
+ rule = mail_user_plugin_getenv(user, rule_name);
+ if (rule == NULL)
+ break;
+
+ if (quota_root_add_rule(root_set, rule, &error) < 0) {
+ *error_r = t_strdup_printf("Invalid rule %s: %s",
+ rule, error);
+ return -1;
+ }
+ rule_name = t_strdup_printf("%s_rule%d", root_name, i);
+ }
+ return 0;
+}
+
+static int
+quota_root_add_warning_rules(struct mail_user *user, const char *root_name,
+ struct quota_root_settings *root_set,
+ const char **error_r)
+{
+ const char *rule_name, *rule, *error;
+ unsigned int i;
+
+ rule_name = t_strconcat(root_name, "_warning", NULL);
+ for (i = 2;; i++) {
+ rule = mail_user_plugin_getenv(user, rule_name);
+ if (rule == NULL)
+ break;
+
+ if (quota_root_add_warning_rule(root_set, rule, &error) < 0) {
+ *error_r = t_strdup_printf("Invalid warning rule: %s",
+ rule);
+ return -1;
+ }
+ rule_name = t_strdup_printf("%s_warning%d", root_name, i);
+ }
+ return 0;
+}
+
+static int
+quota_root_settings_init(struct quota_settings *quota_set, const char *root_def,
+ struct quota_root_settings **set_r,
+ const char **error_r)
{
struct quota_root_settings *root_set;
const struct quota_backend *backend;
@@ -166,8 +125,9 @@
backend = quota_backend_find(backend_name);
if (backend == NULL) {
- i_error("Unknown quota backend: %s", backend_name);
- return NULL;
+ *error_r = t_strdup_printf("Unknown quota backend: %s",
+ backend_name);
+ return -1;
}
root_set = p_new(quota_set->pool, struct quota_root_settings, 1);
@@ -198,11 +158,89 @@
p_array_init(&root_set->rules, quota_set->pool, 4);
p_array_init(&root_set->warning_rules, quota_set->pool, 4);
array_append("a_set->root_sets, &root_set, 1);
- return root_set;
+ *set_r = root_set;
+ return 0;
}
-static struct quota_root *
-quota_root_init(struct quota_root_settings *root_set, struct quota *quota)
+static int
+quota_root_add(struct quota_settings *quota_set, struct mail_user *user,
+ const char *env, const char *root_name, const char **error_r)
+{
+ struct quota_root_settings *root_set;
+
+ if (quota_root_settings_init(quota_set, env, &root_set, error_r) < 0)
+ return -1;
+ if (quota_root_add_rules(user, root_name, root_set, error_r) < 0)
+ return -1;
+ if (quota_root_add_warning_rules(user, root_name, root_set, error_r) < 0)
+ return -1;
+ return 0;
+}
+
+int quota_user_read_settings(struct mail_user *user,
+ struct quota_settings **set_r,
+ const char **error_r)
+{
+ struct quota_settings *quota_set;
+ char root_name[6 + MAX_INT_STRLEN];
+ const char *env, *error;
+ unsigned int i;
+ pool_t pool;
+
+ pool = pool_alloconly_create("quota settings", 2048);
+ quota_set = p_new(pool, struct quota_settings, 1);
+ quota_set->pool = pool;
+ quota_set->test_alloc = quota_default_test_alloc;
+ quota_set->debug = user->mail_debug;
+ quota_set->quota_exceeded_msg =
+ mail_user_plugin_getenv(user, "quota_exceeded_message");
+ if (quota_set->quota_exceeded_msg == NULL)
+ quota_set->quota_exceeded_msg = DEFAULT_QUOTA_EXCEEDED_MSG;
+
+ p_array_init("a_set->root_sets, pool, 4);
+ i_strocpy(root_name, "quota", sizeof(root_name));
+ for (i = 2;; i++) {
+ env = mail_user_plugin_getenv(user, root_name);
+ if (env == NULL)
+ break;
+
+ if (quota_root_add(quota_set, user, env, root_name,
+ &error) < 0) {
+ *error_r = t_strdup_printf("Invalid quota root %s: %s",
+ root_name, error);
+ pool_unref(&pool);
+ return -1;
+ }
+ i_snprintf(root_name, sizeof(root_name), "quota%d", i);
+ }
+ if (array_count("a_set->root_sets) == 0) {
+ pool_unref(&pool);
+ return 0;
+ }
+ *set_r = quota_set;
+ return 1;
+}
+
+void quota_settings_deinit(struct quota_settings **_quota_set)
+{
+ struct quota_settings *quota_set = *_quota_set;
+
+ *_quota_set = NULL;
+
+ pool_unref("a_set->pool);
+}
+
+static void quota_root_deinit(struct quota_root *root)
+{
+ pool_t pool = root->pool;
+
+ root->backend.v.deinit(root);
+ pool_unref(&pool);
+}
+
+static int
+quota_root_init(struct quota_root_settings *root_set, struct quota *quota,
+ struct quota_root **root_r, const char **error_r)
{
struct quota_root *root;
const char *const *tmp;
More information about the dovecot-cvs
mailing list