imap-quota-plugin.c revision e5dca7edde333c2759b0e6b1d0d00b94ea303322
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen/* Copyright (c) 2005-2013 Dovecot authors, see the included COPYING file */
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include "imap-common.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include "str.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include "ostream.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include "imap-quote.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include "mail-namespace.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include "imap-commands.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include "quota.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include "quota-plugin.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include "imap-quota-plugin.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include <stdlib.h>
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#define QUOTA_USER_SEPARATOR ':'
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenconst char *imap_quota_plugin_version = DOVECOT_ABI_VERSION;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenstatic struct module *imap_quota_module;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenstatic imap_client_created_func_t *next_hook_client_created;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenstatic const char *
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenimap_quota_root_get_name(struct mail_user *user, struct mail_user *owner,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen struct quota_root *root)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen{
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen const char *name;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen name = quota_root_get_name(root);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (user == owner || owner == NULL)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen return name;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return t_strdup_printf("%s%c%s", owner->username,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen QUOTA_USER_SEPARATOR, name);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen}
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenstatic void
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenquota_reply_write(string_t *str, struct mail_user *user,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen struct mail_user *owner, struct quota_root *root)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen{
0f66f12eb4cdbf47670975044c88d8f388bf92dfTimo Sirainen const char *name, *const *list;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen unsigned int i;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen uint64_t value, limit;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen int ret = 0;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen str_append(str, "* QUOTA ");
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen name = imap_quota_root_get_name(user, owner, root);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen imap_append_astring(str, name);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen str_append(str, " (");
f7e0daedc6838c45df6b2a0724a57662b92e7df4Timo Sirainen list = quota_root_get_resources(root);
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen for (i = 0; *list != NULL; list++) {
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen ret = quota_get_resource(root, "", *list, &value, &limit);
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen if (ret < 0)
8da8fa22f337c7e9f9ec6183e22f351811478387Timo Sirainen break;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen if (ret > 0) {
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen if (i > 0)
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen str_append_c(str, ' ');
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen str_printfa(str, "%s %llu %llu", *list,
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen (unsigned long long)value,
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen (unsigned long long)limit);
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen i++;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen }
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen }
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen str_append(str, ")\r\n");
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen if (ret < 0)
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen str_append(str, "* BAD Internal quota calculation error\r\n");
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen}
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainenstatic bool cmd_getquotaroot(struct client_command_context *cmd)
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen{
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen struct client *client = cmd->client;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen struct quota_user *quser = QUOTA_USER_CONTEXT(client->user);
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen struct mail_namespace *ns;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen struct mailbox *box;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen struct quota_root_iter *iter;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen struct quota_root *root;
8da8fa22f337c7e9f9ec6183e22f351811478387Timo Sirainen const char *mailbox, *orig_mailbox, *name;
8da8fa22f337c7e9f9ec6183e22f351811478387Timo Sirainen string_t *quotaroot_reply, *quota_reply;
8da8fa22f337c7e9f9ec6183e22f351811478387Timo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen /* <mailbox> */
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen if (!client_read_string_args(cmd, 1, &mailbox))
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen return FALSE;
8da8fa22f337c7e9f9ec6183e22f351811478387Timo Sirainen orig_mailbox = mailbox;
8da8fa22f337c7e9f9ec6183e22f351811478387Timo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen ns = client_find_namespace(cmd, &mailbox);
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen if (ns == NULL)
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen return TRUE;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen if (quser == NULL) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen client_send_tagline(cmd, "OK No quota.");
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen return TRUE;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen }
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen if (ns->owner != NULL && ns->owner != client->user) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen client_send_tagline(cmd, "NO Not showing other users' quota.");
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen return TRUE;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen }
f83a33d8ddb275984cd89835ee8afe0ff584fe91Timo Sirainen
f83a33d8ddb275984cd89835ee8afe0ff584fe91Timo Sirainen box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_READONLY);
f83a33d8ddb275984cd89835ee8afe0ff584fe91Timo Sirainen
f83a33d8ddb275984cd89835ee8afe0ff584fe91Timo Sirainen /* build QUOTAROOT reply and QUOTA reply for all quota roots */
f83a33d8ddb275984cd89835ee8afe0ff584fe91Timo Sirainen quotaroot_reply = t_str_new(128);
f83a33d8ddb275984cd89835ee8afe0ff584fe91Timo Sirainen quota_reply = t_str_new(256);
34861542d8975d85bc87a2e21e40ada22545b672Timo Sirainen str_append(quotaroot_reply, "* QUOTAROOT ");
34861542d8975d85bc87a2e21e40ada22545b672Timo Sirainen imap_append_astring(quotaroot_reply, orig_mailbox);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen iter = quota_root_iter_init(box);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen while ((root = quota_root_iter_next(iter)) != NULL) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen str_append_c(quotaroot_reply, ' ');
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen name = imap_quota_root_get_name(client->user, ns->owner, root);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen imap_append_astring(quotaroot_reply, name);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen quota_reply_write(quota_reply, client->user, ns->owner, root);
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen }
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen quota_root_iter_deinit(&iter);
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen mailbox_free(&box);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen /* send replies */
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (str_len(quota_reply) == 0)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen client_send_tagline(cmd, "OK No quota.");
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen else {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen client_send_line(client, str_c(quotaroot_reply));
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen o_stream_nsend(client->output, str_data(quota_reply),
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen str_len(quota_reply));
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen client_send_tagline(cmd, "OK Getquotaroot completed.");
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen }
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen return TRUE;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen}
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenstatic bool
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenparse_quota_root(struct mail_user *user, const char *root_name,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen struct mail_user **owner_r, struct quota_root **root_r)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen{
77717f1e9e8442fd2cdbca87cbc45c03d0b5fcaeTimo Sirainen const char *p;
9dd7e489b8f0049ca9111393f08f73bac3591b89Timo Sirainen
9dd7e489b8f0049ca9111393f08f73bac3591b89Timo Sirainen *owner_r = user;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen *root_r = quota_root_lookup(user, root_name);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (*root_r != NULL || !user->admin)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen return *root_r != NULL;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen /* we're an admin. see if there's a quota root for another user. */
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen p = strchr(root_name, QUOTA_USER_SEPARATOR);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (p != NULL) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen *owner_r = mail_user_find(user, t_strdup_until(root_name, p));
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen *root_r = *owner_r == NULL ? NULL :
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen quota_root_lookup(*owner_r, p + 1);
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen }
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen return *root_r != NULL;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen}
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainenstatic bool cmd_getquota(struct client_command_context *cmd)
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen{
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen struct mail_user *owner;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen struct quota_root *root;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen const char *root_name;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen string_t *quota_reply;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen /* <quota root> */
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen if (!client_read_string_args(cmd, 1, &root_name))
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen return FALSE;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen if (!parse_quota_root(cmd->client->user, root_name, &owner, &root)) {
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen client_send_tagline(cmd, "NO Quota root doesn't exist.");
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen return TRUE;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen }
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen quota_reply = t_str_new(128);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen quota_reply_write(quota_reply, cmd->client->user, owner, root);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen o_stream_nsend(cmd->client->output, str_data(quota_reply),
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen str_len(quota_reply));
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen client_send_tagline(cmd, "OK Getquota completed.");
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen return TRUE;
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen}
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainenstatic bool cmd_setquota(struct client_command_context *cmd)
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen{
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen struct quota_root *root;
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen struct mail_user *owner;
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen const struct imap_arg *args, *list_args;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen const char *root_name, *name, *value_str, *error;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen uint64_t value;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen /* <quota root> <resource limits> */
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (!client_read_args(cmd, 2, 0, &args))
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen return FALSE;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (!imap_arg_get_astring(&args[0], &root_name) ||
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen !imap_arg_get_list(&args[1], &list_args)) {
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen return TRUE;
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen }
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen if (!cmd->client->user->admin) {
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen client_send_tagline(cmd, "NO Quota can be changed only by admin.");
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen return TRUE;
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen }
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
091e808a5af4dbc40aacde8dd1fbf98fae52e6c1Timo Sirainen if (!parse_quota_root(cmd->client->user, root_name, &owner, &root)) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen client_send_tagline(cmd, "NO Quota root doesn't exist.");
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen return TRUE;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen }
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen for (; !IMAP_ARG_IS_EOL(list_args); list_args += 2) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (!imap_arg_get_atom(&list_args[0], &name) ||
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen !imap_arg_get_atom(&list_args[1], &value_str) ||
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen str_to_uint64(value_str, &value) < 0) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen return TRUE;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen }
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (quota_set_resource(root, name, value, &error) < 0) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen client_send_command_error(cmd, error);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen return TRUE;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen }
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen }
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen client_send_tagline(cmd, "OK Setquota completed.");
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen return TRUE;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen}
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainenstatic void imap_quota_client_created(struct client **client)
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen{
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen if (mail_user_is_plugin_loaded((*client)->user, imap_quota_module))
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen str_append((*client)->capability_string, " QUOTA");
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen if (next_hook_client_created != NULL)
ef0fe74b5d663fe9966b98f39d2eae5ec2e5ac6cTimo Sirainen next_hook_client_created(client);
34861542d8975d85bc87a2e21e40ada22545b672Timo Sirainen}
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainenvoid imap_quota_plugin_init(struct module *module)
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen{
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen command_register("GETQUOTAROOT", cmd_getquotaroot, 0);
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen command_register("GETQUOTA", cmd_getquota, 0);
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen command_register("SETQUOTA", cmd_setquota, 0);
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen
4498761e9ee18c96a19ce3029258a6390efeb092Timo Sirainen imap_quota_module = module;
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen next_hook_client_created =
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen imap_client_created_hook_set(imap_quota_client_created);
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen}
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainenvoid imap_quota_plugin_deinit(void)
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen{
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen command_unregister("GETQUOTAROOT");
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen command_unregister("GETQUOTA");
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen command_unregister("SETQUOTA");
b6ff64ea9a8615271ffdfde1aad2da2fd1b0ba1fTimo Sirainen
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen imap_client_created_hook_set(next_hook_client_created);
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen}
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainenconst char *imap_quota_plugin_dependencies[] = { "quota", NULL };
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainenconst char imap_quota_plugin_binary_dependency[] = "imap";
b22f3db16d33b8e509b7331e46108c313e7f3b94Timo Sirainen