diff src/plugins/imap-quota/imap-quota-plugin.c @ 3738:732b62dc1976 HEAD

Added beginnings of plugin infrastructure. TODO: These could be optionally compiled into binaries with some configure options. Added quota plugin and a new trash plugin. Not very well tested.
author Timo Sirainen <tss@iki.fi>
date Sat, 10 Dec 2005 21:44:45 +0200
parents
children b752272e6355
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/imap-quota/imap-quota-plugin.c	Sat Dec 10 21:44:45 2005 +0200
@@ -0,0 +1,198 @@
+/* Copyright (C) 2005 Timo Sirainen */
+
+#include "common.h"
+#include "str.h"
+#include "imap-quote.h"
+#include "commands.h"
+#include "quota.h"
+#include "quota-plugin.h"
+#include "imap-quota-plugin.h"
+
+#include <stdlib.h>
+
+static void
+quota_send(struct client_command_context *cmd, struct quota_root *root)
+{
+        const char *const *list;
+	string_t *str;
+	unsigned int i;
+	uint64_t value, limit;
+	int ret;
+
+	t_push();
+
+	str = t_str_new(128);
+	str_append(str, "* QUOTA ");
+	imap_quote_append_string(str, quota_root_get_name(root), FALSE);
+
+	str_append(str, " (");
+	list = quota_root_get_resources(root);
+	for (i = 0; *list != NULL; list++, i++) {
+		ret = quota_get_resource(root, *list, &value, &limit);
+		if (ret > 0) {
+			if (i > 0)
+				str_append_c(str, ' ');
+			str_printfa(str, "%s %llu %llu", *list,
+				    (unsigned long long)value,
+				    (unsigned long long)limit);
+		} else if (ret < 0) {
+			client_send_line(cmd->client, t_strconcat(
+				"* BAD ", quota_last_error(quota), NULL));
+		}
+	}
+	str_append_c(str, ')');
+	client_send_line(cmd->client, str_c(str));
+
+	t_pop();
+}
+
+static int cmd_getquotaroot(struct client_command_context *cmd)
+{
+	struct mail_storage *storage;
+	struct mailbox *box;
+	struct quota_root_iter *iter;
+        struct quota_root *root;
+	const char *mailbox;
+	string_t *str;
+
+	/* <mailbox> */
+	if (!client_read_string_args(cmd, 1, &mailbox))
+		return FALSE;
+
+	storage = client_find_storage(cmd, &mailbox);
+	if (storage == NULL)
+		return TRUE;
+
+	box = mailbox_open(storage, mailbox, NULL, (MAILBOX_OPEN_READONLY |
+						    MAILBOX_OPEN_FAST |
+						    MAILBOX_OPEN_KEEP_RECENT));
+	if (box == NULL) {
+		client_send_storage_error(cmd, storage);
+		return TRUE;
+	}
+
+	if (quota == NULL) {
+		client_send_tagline(cmd, "OK No quota.");
+		return TRUE;
+	}
+
+	/* send QUOTAROOT reply */
+	str = t_str_new(128);
+	str_append(str, "* QUOTAROOT ");
+	imap_quote_append_string(str, mailbox, FALSE);
+
+	iter = quota_root_iter_init(quota, box);
+	while ((root = quota_root_iter_next(iter)) != NULL) {
+		str_append_c(str, ' ');
+		imap_quote_append_string(str, quota_root_get_name(root), FALSE);
+	}
+	if (quota_root_iter_deinit(iter) < 0) {
+		/* some failure, send as untagged error */
+		client_send_line(cmd->client, t_strconcat(
+			"* BAD ", quota_last_error(quota), NULL));
+	}
+	client_send_line(cmd->client, str_c(str));
+
+	/* send QUOTA reply for each quotaroot */
+	iter = quota_root_iter_init(quota, box);
+	while ((root = quota_root_iter_next(iter)) != NULL)
+		quota_send(cmd, root);
+	if (quota_root_iter_deinit(iter) < 0) {
+		/* some failure, send as untagged error */
+		client_send_line(cmd->client, t_strconcat(
+			"* BAD ", quota_last_error(quota), NULL));
+	}
+
+	mailbox_close(box);
+
+	client_send_tagline(cmd, "OK Getquotaroot completed.");
+	return TRUE;
+}
+
+static int cmd_getquota(struct client_command_context *cmd)
+{
+	const char *root_name;
+        struct quota_root *root;
+
+	/* <quota root> */
+	if (!client_read_string_args(cmd, 1, &root_name))
+		return FALSE;
+
+	if (quota == NULL) {
+		client_send_tagline(cmd, "OK No quota.");
+		return TRUE;
+	}
+
+	root = quota_root_lookup(quota, root_name);
+	if (root == NULL) {
+		client_send_tagline(cmd, "NO Quota root doesn't exist.");
+		return TRUE;
+	}
+
+	quota_send(cmd, root);
+	client_send_tagline(cmd, "OK Getquota completed.");
+	return TRUE;
+}
+
+static int cmd_setquota(struct client_command_context *cmd)
+{
+	struct quota_root *root;
+        struct imap_arg *args, *arg;
+	const char *root_name, *name;
+	uint64_t value;
+
+	/* <quota root> <resource limits> */
+	if (!client_read_args(cmd, 2, 0, &args))
+		return FALSE;
+
+	root_name = imap_arg_string(&args[0]);
+	if (args[1].type != IMAP_ARG_LIST || root_name == NULL) {
+		client_send_command_error(cmd, "Invalid arguments.");
+		return TRUE;
+	}
+
+	if (quota == NULL) {
+		client_send_tagline(cmd, "OK No quota.");
+		return TRUE;
+	}
+
+	root = quota_root_lookup(quota, root_name);
+	if (root == NULL) {
+		client_send_tagline(cmd, "NO Quota root doesn't exist.");
+		return TRUE;
+	}
+
+        arg = IMAP_ARG_LIST(&args[1])->args;
+	for (; arg->type != IMAP_ARG_EOL; arg += 2) {
+		name = imap_arg_string(arg);
+		if (name == NULL || arg[1].type != IMAP_ARG_ATOM ||
+		    !is_numeric(IMAP_ARG_STR(&arg[1]), '\0')) {
+			client_send_command_error(cmd, "Invalid arguments.");
+			return TRUE;
+		}
+
+                value = strtoull(IMAP_ARG_STR_NONULL(&arg[1]), NULL, 10);
+		if (quota_set_resource(root, name, value) < 0) {
+			client_send_command_error(cmd,
+						  quota_last_error(quota));
+			return TRUE;
+		}
+	}
+
+	client_send_tagline(cmd, "OK Setquota completed.");
+	return TRUE;
+}
+
+void imap_quota_init(void)
+{
+	command_register("GETQUOTAROOT", cmd_getquotaroot);
+	command_register("GETQUOTA", cmd_getquota);
+	command_register("SETQUOTA", cmd_setquota);
+}
+
+void imap_quota_deinit(void)
+{
+	command_unregister("GETQUOTAROOT");
+	command_unregister("GETQUOTA");
+	command_unregister("SETQUOTA");
+}