imap-quota-plugin.c revision 08d6658a4e2ec8104cd1307f6baa75fdb07a24f8
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "imap-common.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "str.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "imap-quote.h"
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen#include "mail-namespace.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "imap-commands.h"
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen#include "quota.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "quota-plugin.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "imap-quota-plugin.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include <stdlib.h>
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen#define QUOTA_USER_SEPARATOR ':'
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainenconst char *imap_quota_plugin_version = PACKAGE_VERSION;
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainenstatic void (*next_hook_client_created)(struct client **client);
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainenstatic const char *
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenimap_quota_root_get_name(struct mail_user *user, struct mail_user *owner,
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct quota_root *root)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
373492be949e159fda651807b3acda2c5c077027Timo Sirainen const char *name;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen name = quota_root_get_name(root);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if (user == owner || owner == NULL)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return name;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return t_strdup_printf("%s%c%s", owner->username,
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen QUOTA_USER_SEPARATOR, name);
373492be949e159fda651807b3acda2c5c077027Timo Sirainen}
373492be949e159fda651807b3acda2c5c077027Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenstatic void
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenquota_send(struct client_command_context *cmd, struct mail_user *owner,
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct quota_root *root)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen const char *name, *const *list;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen string_t *str;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen unsigned int i;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen uint64_t value, limit;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen int ret;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen str = t_str_new(128);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen str_append(str, "* QUOTA ");
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen name = imap_quota_root_get_name(cmd->client->user, owner, root);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen imap_quote_append_string(str, name, FALSE);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen str_append(str, " (");
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen list = quota_root_get_resources(root);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen for (i = 0; *list != NULL; list++) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen ret = quota_get_resource(root, "", *list, &value, &limit);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (ret > 0) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (i > 0)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen str_append_c(str, ' ');
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen str_printfa(str, "%s %llu %llu", *list,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen (unsigned long long)value,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen (unsigned long long)limit);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen i++;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen } else if (ret < 0) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen client_send_line(cmd->client,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen "* BAD Internal quota calculation error");
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen }
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen }
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen str_append_c(str, ')');
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen client_send_line(cmd->client, str_c(str));
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen}
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenstatic bool cmd_getquotaroot(struct client_command_context *cmd)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct client *client = cmd->client;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct quota_user *quser = QUOTA_USER_CONTEXT(client->user);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct mail_storage *storage;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct mail_namespace *ns;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct mailbox *box;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct quota_root_iter *iter;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct quota_root *root;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen const char *orig_mailbox, *mailbox, *name;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen string_t *str;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen /* <mailbox> */
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (!client_read_string_args(cmd, 1, &mailbox))
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen return FALSE;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen orig_mailbox = mailbox;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen storage = client_find_storage(cmd, &mailbox);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (storage == NULL)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen return TRUE;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen box = mailbox_open(&storage, mailbox, NULL, (MAILBOX_OPEN_READONLY |
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen MAILBOX_OPEN_FAST |
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen MAILBOX_OPEN_KEEP_RECENT));
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (box == NULL) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen client_send_storage_error(cmd, storage);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen return TRUE;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen ns = mail_storage_get_namespace(storage);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (quser == NULL) {
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen mailbox_close(&box);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen client_send_tagline(cmd, "OK No quota.");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return TRUE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (ns->owner != NULL && ns->owner != client->user &&
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen !client->user->admin) {
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen mailbox_close(&box);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen client_send_tagline(cmd, "NO Not showing other users' quota.");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return TRUE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
380dbb60ae291cbe39d1f710284562ca9167150bTimo Sirainen
380dbb60ae291cbe39d1f710284562ca9167150bTimo Sirainen /* send QUOTAROOT reply */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str = t_str_new(128);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_append(str, "* QUOTAROOT ");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen imap_quote_append_string(str, orig_mailbox, FALSE);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen iter = quota_root_iter_init(box);
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen while ((root = quota_root_iter_next(iter)) != NULL) {
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen str_append_c(str, ' ');
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen name = imap_quota_root_get_name(client->user, ns->owner, root);
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen imap_quote_append_string(str, name, FALSE);
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen }
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen quota_root_iter_deinit(&iter);
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen client_send_line(client, str_c(str));
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen /* send QUOTA reply for each quotaroot */
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen iter = quota_root_iter_init(box);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen while ((root = quota_root_iter_next(iter)) != NULL)
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen quota_send(cmd, ns->owner, root);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen quota_root_iter_deinit(&iter);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mailbox_close(&box);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen client_send_tagline(cmd, "OK Getquotaroot completed.");
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen return TRUE;
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic bool cmd_getquota(struct client_command_context *cmd)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct mail_user *owner = cmd->client->user;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct quota_root *root;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *root_name, *p;
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* <quota root> */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (!client_read_string_args(cmd, 1, &root_name))
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return FALSE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen root = quota_root_lookup(cmd->client->user, root_name);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (root == NULL && cmd->client->user->admin) {
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen /* we're an admin. see if there's a quota root for another
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen user. */
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen p = strchr(root_name, QUOTA_USER_SEPARATOR);
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen if (p != NULL) {
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen owner = mail_user_find(cmd->client->user,
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen t_strdup_until(root_name, p));
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen root = owner == NULL ? NULL :
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen quota_root_lookup(owner, p + 1);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (root == NULL) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen client_send_tagline(cmd, "NO Quota root doesn't exist.");
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen return TRUE;
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen }
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen quota_send(cmd, owner, root);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen client_send_tagline(cmd, "OK Getquota completed.");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return TRUE;
57d2429fae575e96ca276355af675deb66b76d00Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic bool cmd_setquota(struct client_command_context *cmd)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
57d2429fae575e96ca276355af675deb66b76d00Timo Sirainen struct quota_root *root;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const struct imap_arg *args, *arg;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *root_name, *name, *error;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen uint64_t value;
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* <quota root> <resource limits> */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (!client_read_args(cmd, 2, 0, &args))
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return FALSE;
61618d4c58080570f689614fec204ae14e90cef2Timo Sirainen
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainen root_name = imap_arg_string(&args[0]);
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainen if (args[1].type != IMAP_ARG_LIST || root_name == NULL) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return TRUE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen root = quota_root_lookup(cmd->client->user, root_name);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (root == NULL) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen client_send_tagline(cmd, "NO Quota root doesn't exist.");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return TRUE;
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen arg = IMAP_ARG_LIST_ARGS(&args[1]);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen for (; arg->type != IMAP_ARG_EOL; arg += 2) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen name = imap_arg_string(arg);
c6f894e1522f7b0b6068c228900914073c145175Timo Sirainen if (name == NULL || arg[1].type != IMAP_ARG_ATOM ||
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen !is_numeric(IMAP_ARG_STR(&arg[1]), '\0')) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return TRUE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen value = strtoull(IMAP_ARG_STR_NONULL(&arg[1]), NULL, 10);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (quota_set_resource(root, name, value, &error) < 0) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen client_send_command_error(cmd, error);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return TRUE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen client_send_tagline(cmd, "OK Setquota completed.");
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen return TRUE;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen}
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainenstatic void imap_quota_client_created(struct client **client)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen{
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen str_append((*client)->capability_string, " QUOTA");
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (next_hook_client_created != NULL)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen next_hook_client_created(client);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen}
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainenvoid imap_quota_plugin_init(void)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen{
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen command_register("GETQUOTAROOT", cmd_getquotaroot, 0);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen command_register("GETQUOTA", cmd_getquota, 0);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen command_register("SETQUOTA", cmd_setquota, 0);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen next_hook_client_created = hook_client_created;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen hook_client_created = imap_quota_client_created;
c6f894e1522f7b0b6068c228900914073c145175Timo Sirainen}
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainenvoid imap_quota_plugin_deinit(void)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen{
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen command_unregister("GETQUOTAROOT");
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen command_unregister("GETQUOTA");
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen command_unregister("SETQUOTA");
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen hook_client_created = next_hook_client_created;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen