changeset 5704:4bf8438b497f HEAD

Allow backend-specific quota rules with backend=<string>. Support Maildir++ quota limit strings with Maildir++ backend.
author Timo Sirainen <tss@iki.fi>
date Tue, 12 Jun 2007 18:54:23 +0300
parents 96b796e46d0e
children 4c62af215aca
files src/plugins/quota/quota-dict.c src/plugins/quota/quota-dirsize.c src/plugins/quota/quota-fs.c src/plugins/quota/quota-maildir.c src/plugins/quota/quota-private.h src/plugins/quota/quota.c
diffstat 6 files changed, 78 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/quota/quota-dict.c	Tue Jun 12 18:39:49 2007 +0300
+++ b/src/plugins/quota/quota-dict.c	Tue Jun 12 18:54:23 2007 +0300
@@ -167,6 +167,7 @@
 		dict_quota_init,
 		dict_quota_deinit,
 		NULL,
+		NULL,
 		dict_quota_root_get_resources,
 		dict_quota_get_resource,
 		dict_quota_update
--- a/src/plugins/quota/quota-dirsize.c	Tue Jun 12 18:39:49 2007 +0300
+++ b/src/plugins/quota/quota-dirsize.c	Tue Jun 12 18:54:23 2007 +0300
@@ -208,6 +208,7 @@
 		NULL,
 		dirsize_quota_deinit,
 		NULL,
+		NULL,
 		dirsize_quota_root_get_resources,
 		dirsize_quota_get_resource,
 		dirsize_quota_update
--- a/src/plugins/quota/quota-fs.c	Tue Jun 12 18:39:49 2007 +0300
+++ b/src/plugins/quota/quota-fs.c	Tue Jun 12 18:54:23 2007 +0300
@@ -291,6 +291,7 @@
 		fs_quota_alloc,
 		NULL,
 		fs_quota_deinit,
+		NULL,
 
 		fs_quota_storage_added,
 
--- a/src/plugins/quota/quota-maildir.c	Tue Jun 12 18:39:49 2007 +0300
+++ b/src/plugins/quota/quota-maildir.c	Tue Jun 12 18:54:23 2007 +0300
@@ -345,38 +345,55 @@
 	return maildirsize_recalculate_finish(root, ret);
 }
 
+static bool
+maildir_parse_limit(const char *str, uint64_t *bytes_r, uint64_t *count_r)
+{
+	const char *const *limit;
+	unsigned long long value;
+	char *pos;
+	bool ret = TRUE;
+
+	*bytes_r = (uint64_t)-1;
+	*count_r = (uint64_t)-1;
+
+	/* 0 values mean unlimited */
+	for (limit = t_strsplit(str, ","); *limit != NULL; limit++) {
+		value = strtoull(*limit, &pos, 10);
+		if (pos[0] != '\0' && pos[1] == '\0') {
+			switch (pos[0]) {
+			case 'C':
+				if (value != 0)
+					*count_r = value;
+				break;
+			case 'S':
+				if (value != 0)
+					*bytes_r = value;
+				break;
+			default:
+				ret = FALSE;
+				break;
+			}
+		} else {
+			ret = FALSE;
+		}
+	}
+	return ret;
+}
+
 static int maildirsize_parse(struct maildir_quota_root *root,
 			     int fd, const char *const *lines)
 {
-	unsigned long long bytes;
 	uint64_t message_bytes_limit, message_count_limit;
 	long long bytes_diff, total_bytes;
 	int count_diff, total_count;
 	unsigned int line_count = 0;
-	const char *const *limit;
-	char *pos;
 
 	if (*lines == NULL)
 		return -1;
 
-	/* first line contains the limits. 0 value mean unlimited. */
-	message_bytes_limit = (uint64_t)-1;
-	message_count_limit = (uint64_t)-1;
-	for (limit = t_strsplit(lines[0], ","); *limit != NULL; limit++) {
-		bytes = strtoull(*limit, &pos, 10);
-		if (pos[0] != '\0' && pos[1] == '\0') {
-			switch (pos[0]) {
-			case 'C':
-				if (bytes != 0)
-					message_count_limit = bytes;
-				break;
-			case 'S':
-				if (bytes != 0)
-					message_bytes_limit = bytes;
-				break;
-			}
-		}
-	}
+	/* first line contains the limits */
+	(void)maildir_parse_limit(lines[0], &message_bytes_limit,
+				  &message_count_limit);
 
 	if (!root->master_message_limits) {
 		/* we don't know the limits, use whatever the file says */
@@ -586,6 +603,23 @@
 	i_free(root);
 }
 
+static bool
+maildir_quota_parse_rule(struct quota_root *root __attr_unused__,
+			 struct quota_rule *rule,
+			 const char *str, const char **error_r)
+{
+	uint64_t bytes, count;
+
+	if (!maildir_parse_limit(str, &bytes, &count)) {
+		*error_r = "Invalid Maildir++ quota rule";
+		return FALSE;
+	}
+
+	rule->bytes_limit = bytes;
+	rule->count_limit = count;
+	return TRUE;
+}
+
 static void
 maildir_quota_root_storage_added(struct quota_root *_root,
 				 struct mail_storage *storage)
@@ -675,6 +709,7 @@
 		maildir_quota_alloc,
 		NULL,
 		maildir_quota_deinit,
+		maildir_quota_parse_rule,
 		maildir_quota_storage_added,
 		maildir_quota_root_get_resources,
 		maildir_quota_get_resource,
--- a/src/plugins/quota/quota-private.h	Tue Jun 12 18:39:49 2007 +0300
+++ b/src/plugins/quota/quota-private.h	Tue Jun 12 18:54:23 2007 +0300
@@ -19,11 +19,20 @@
 	unsigned int counting:1;
 };
 
+struct quota_rule {
+	char *mailbox_name;
+
+	int64_t bytes_limit, count_limit;
+};
+
 struct quota_backend_vfuncs {
 	struct quota_root *(*alloc)(void);
 	int (*init)(struct quota_root *root, const char *args);
 	void (*deinit)(struct quota_root *root);
 
+	bool (*parse_rule)(struct quota_root *root, struct quota_rule *rule,
+			   const char *str, const char **error_r);
+
 	/* called once for each backend */
 	void (*storage_added)(struct quota *quota,
 			      struct mail_storage *storage);
@@ -44,12 +53,6 @@
 	struct quota_backend_vfuncs v;
 };
 
-struct quota_rule {
-	char *mailbox_name;
-
-	int64_t bytes_limit, count_limit;
-};
-
 struct quota_root {
 	pool_t pool;
 
--- a/src/plugins/quota/quota.c	Tue Jun 12 18:39:49 2007 +0300
+++ b/src/plugins/quota/quota.c	Tue Jun 12 18:54:23 2007 +0300
@@ -198,7 +198,16 @@
 		}
 	}
 
-	for (args = t_strsplit(p, ":"); *args != NULL; args++) {
+	if (strncmp(p, "backend=", 8) == 0) {
+		if (!root->backend.v.parse_rule(root, rule, p, error_r))
+			ret = -1;
+		p = "";
+		args = &p;
+	} else {
+		args = t_strsplit(p, ":");
+	}
+
+	for (; *args != NULL; args++) {
 		if (strncmp(*args, "storage=", 8) == 0)
 			rule->bytes_limit = strtoll(*args + 8, NULL, 10) * 1024;
 		else if (strncmp(*args, "bytes=", 6) == 0)