imap-quota-plugin.c revision d12d1accd6060eee70375f1e6122425a159114e4
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2005-2011 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "imap-common.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "str.h"
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen#include "ostream.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "imap-quote.h"
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#include "mail-namespace.h"
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen#include "imap-commands.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "quota.h"
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#include "quota-plugin.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "imap-quota-plugin.h"
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include <stdlib.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define QUOTA_USER_SEPARATOR ':'
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char *imap_quota_plugin_version = DOVECOT_VERSION;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
8887bf3757d51d73887dd20b1db3334d867d3817Timo Sirainenstatic struct module *imap_quota_module;
8887bf3757d51d73887dd20b1db3334d867d3817Timo Sirainenstatic void (*next_hook_client_created)(struct client **client);
369a1084c500a9df7448ffa9409ce32e42060bc2Timo Sirainen
8887bf3757d51d73887dd20b1db3334d867d3817Timo Sirainenstatic const char *
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainenimap_quota_root_get_name(struct mail_user *user, struct mail_user *owner,
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen struct quota_root *root)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *name;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen name = quota_root_get_name(root);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (user == owner || owner == NULL)
b7b81543899e306c71e6152516d8698416162bcbTimo Sirainen return name;
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen return t_strdup_printf("%s%c%s", owner->username,
e12648867876aaec17e06ee4caef0bb60363449dTimo Sirainen QUOTA_USER_SEPARATOR, name);
e12648867876aaec17e06ee4caef0bb60363449dTimo Sirainen}
e12648867876aaec17e06ee4caef0bb60363449dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenquota_reply_write(string_t *str, struct mail_user *user,
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen struct mail_user *owner, struct quota_root *root)
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *name, *const *list;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint64_t value, limit;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(str, "* QUOTA ");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen name = imap_quota_root_get_name(user, owner, root);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_quote_append_string(str, name, FALSE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(str, " (");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen list = quota_root_get_resources(root);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen for (i = 0; *list != NULL; list++) {
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen ret = quota_get_resource(root, "", *list, &value, &limit);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen if (ret < 0)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret > 0) {
811f2e26d9782d9cb99fdf82e18ffa0a77564fe2Timo Sirainen if (i > 0)
811f2e26d9782d9cb99fdf82e18ffa0a77564fe2Timo Sirainen str_append_c(str, ' ');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_printfa(str, "%s %llu %llu", *list,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (unsigned long long)value,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (unsigned long long)limit);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i++;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(str, ")\r\n");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen if (ret < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(str, "* BAD Internal quota calculation error\r\n");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic bool cmd_getquotaroot(struct client_command_context *cmd)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct client *client = cmd->client;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct quota_user *quser = QUOTA_USER_CONTEXT(client->user);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_namespace *ns;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox *box;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct quota_root_iter *iter;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct quota_root *root;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mailbox_name_status status;
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen const char *mailbox, *storage_name, *name;
2a734f36105e33ab452d057df6bc7a2b7d9f96f0Timo Sirainen string_t *quotaroot_reply, *quota_reply;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen /* <mailbox> */
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen if (!client_read_string_args(cmd, 1, &mailbox))
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen return FALSE;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ns = client_find_namespace(cmd, mailbox, &storage_name, &status);
d2475500ee2a5f3c07eb22886797cef0e11ce7c4Timo Sirainen if (ns == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (quser == NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_tagline(cmd, "OK No quota.");
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ns->owner != NULL && ns->owner != client->user &&
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen !client->user->admin) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen client_send_tagline(cmd, "NO Not showing other users' quota.");
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return TRUE;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (status == MAILBOX_NAME_INVALID) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen client_fail_mailbox_name_status(cmd, mailbox, NULL, status);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return TRUE;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen box = mailbox_alloc(ns->list, storage_name, MAILBOX_FLAG_READONLY |
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen MAILBOX_FLAG_KEEP_RECENT);
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen /* build QUOTAROOT reply and QUOTA reply for all quota roots */
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen quotaroot_reply = t_str_new(128);
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen quota_reply = t_str_new(256);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(quotaroot_reply, "* QUOTAROOT ");
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen imap_quote_append_string(quotaroot_reply, mailbox, FALSE);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen iter = quota_root_iter_init(box);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen while ((root = quota_root_iter_next(iter)) != NULL) {
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen str_append_c(quotaroot_reply, ' ');
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen name = imap_quota_root_get_name(client->user, ns->owner, root);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen imap_quote_append_string(quotaroot_reply, name, FALSE);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen quota_reply_write(quota_reply, client->user, ns->owner, root);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen quota_root_iter_deinit(&iter);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen mailbox_free(&box);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* send replies */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (str_len(quota_reply) == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_tagline(cmd, "OK No quota.");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else {
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen client_send_line(client, str_c(quotaroot_reply));
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen o_stream_send(client->output, str_data(quota_reply),
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen str_len(quota_reply));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_tagline(cmd, "OK Getquotaroot completed.");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen return TRUE;
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen}
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainenstatic bool cmd_getquota(struct client_command_context *cmd)
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen{
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen struct mail_user *owner = cmd->client->user;
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen struct quota_root *root;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen const char *root_name, *p;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen string_t *quota_reply;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen /* <quota root> */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!client_read_string_args(cmd, 1, &root_name))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen root = quota_root_lookup(cmd->client->user, root_name);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (root == NULL && cmd->client->user->admin) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we're an admin. see if there's a quota root for another
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen user. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen p = strchr(root_name, QUOTA_USER_SEPARATOR);
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen if (p != NULL) {
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen owner = mail_user_find(cmd->client->user,
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen t_strdup_until(root_name, p));
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen root = owner == NULL ? NULL :
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen quota_root_lookup(owner, p + 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainen if (root == NULL) {
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainen client_send_tagline(cmd, "NO Quota root doesn't exist.");
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen quota_reply = t_str_new(128);
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen quota_reply_write(quota_reply, cmd->client->user, owner, root);
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen o_stream_send(cmd->client->output, str_data(quota_reply),
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen str_len(quota_reply));
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_tagline(cmd, "OK Getquota completed.");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenstatic bool cmd_setquota(struct client_command_context *cmd)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct quota_root *root;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct imap_arg *args, *list_args;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *root_name, *name, *value_str, *error;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint64_t value;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen /* <quota root> <resource limits> */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!client_read_args(cmd, 2, 0, &args))
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen return FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!imap_arg_get_astring(&args[0], &root_name) ||
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen !imap_arg_get_list(&args[1], &list_args)) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return TRUE;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen root = quota_root_lookup(cmd->client->user, root_name);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (root == NULL) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen client_send_tagline(cmd, "NO Quota root doesn't exist.");
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
7c95b03620a03a43dd72d39608cea5fc77393ad6Timo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen for (; !IMAP_ARG_IS_EOL(list_args); list_args += 2) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (!imap_arg_get_atom(&list_args[0], &name) ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen !imap_arg_get_atom(&list_args[1], &value_str) ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_to_uint64(value_str, &value) < 0) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen client_send_command_error(cmd, "Invalid arguments.");
eac3948d67eff8623d51aeaea9eca582f3aec677Timo Sirainen return TRUE;
2674b4f0cf8f3c203d8e56b29735f5e267038dafTimo Sirainen }
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen
48136ae5a0eb49daa44e343553f3688a500307e2Timo Sirainen if (quota_set_resource(root, name, value, &error) < 0) {
48136ae5a0eb49daa44e343553f3688a500307e2Timo Sirainen client_send_command_error(cmd, error);
2674b4f0cf8f3c203d8e56b29735f5e267038dafTimo Sirainen return TRUE;
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen }
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen }
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_tagline(cmd, "OK Setquota completed.");
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return TRUE;
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen}
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic void imap_quota_client_created(struct client **client)
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (mail_user_is_plugin_loaded((*client)->user, imap_quota_module))
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen str_append((*client)->capability_string, " QUOTA");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (next_hook_client_created != NULL)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen next_hook_client_created(client);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid imap_quota_plugin_init(struct module *module)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen command_register("GETQUOTAROOT", cmd_getquotaroot, 0);
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen command_register("GETQUOTA", cmd_getquota, 0);
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen command_register("SETQUOTA", cmd_setquota, 0);
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_quota_module = module;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen next_hook_client_created =
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen imap_client_created_hook_set(imap_quota_client_created);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid imap_quota_plugin_deinit(void)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
aa0647f2debf0d48d504a321186f66c85596aaf4Timo Sirainen command_unregister("GETQUOTAROOT");
aa0647f2debf0d48d504a321186f66c85596aaf4Timo Sirainen command_unregister("GETQUOTA");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen command_unregister("SETQUOTA");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_client_created_hook_set(next_hook_client_created);
aa0647f2debf0d48d504a321186f66c85596aaf4Timo Sirainen}
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenconst char *imap_quota_plugin_dependencies[] = { "quota", NULL };
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char imap_quota_plugin_binary_dependency[] = "imap";
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen