Mercurial > dovecot > original-hg > dovecot-1.2
diff src/plugins/imap-quota/imap-quota-plugin.c @ 8470:e4f319453cb2 HEAD
Quota works now properly with shared mailboxes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 21 Nov 2008 19:45:57 +0200 |
parents | d4eab639c253 |
children | b9faf4db2a9f |
line wrap: on
line diff
--- a/src/plugins/imap-quota/imap-quota-plugin.c Fri Nov 21 19:45:22 2008 +0200 +++ b/src/plugins/imap-quota/imap-quota-plugin.c Fri Nov 21 19:45:57 2008 +0200 @@ -3,6 +3,7 @@ #include "common.h" #include "str.h" #include "imap-quote.h" +#include "mail-namespace.h" #include "commands.h" #include "quota.h" #include "quota-plugin.h" @@ -10,12 +11,28 @@ #include <stdlib.h> +#define QUOTA_USER_SEPARATOR ':' + const char *imap_quota_plugin_version = PACKAGE_VERSION; +static const char * +imap_quota_root_get_name(struct mail_user *user, struct mail_user *owner, + struct quota_root *root) +{ + const char *name; + + name = quota_root_get_name(root); + if (user == owner) + return name; + return t_strdup_printf("%s%c%s", owner->username, + QUOTA_USER_SEPARATOR, name); +} + static void -quota_send(struct client_command_context *cmd, struct quota_root *root) +quota_send(struct client_command_context *cmd, struct mail_user *owner, + struct quota_root *root) { - const char *const *list; + const char *name, *const *list; string_t *str; unsigned int i; uint64_t value, limit; @@ -23,7 +40,8 @@ str = t_str_new(128); str_append(str, "* QUOTA "); - imap_quote_append_string(str, quota_root_get_name(root), FALSE); + name = imap_quota_root_get_name(cmd->client->user, owner, root); + imap_quote_append_string(str, name, FALSE); str_append(str, " ("); list = quota_root_get_resources(root); @@ -47,11 +65,13 @@ static bool cmd_getquotaroot(struct client_command_context *cmd) { + struct client *client = cmd->client; struct mail_storage *storage; + struct mail_namespace *ns; struct mailbox *box; struct quota_root_iter *iter; struct quota_root *root; - const char *orig_mailbox, *mailbox; + const char *orig_mailbox, *mailbox, *name; string_t *str; /* <mailbox> */ @@ -71,11 +91,17 @@ return TRUE; } - if (quota_set == NULL) { + ns = mail_storage_get_namespace(storage); + if (quota_set == NULL || ns->owner == NULL) { mailbox_close(&box); client_send_tagline(cmd, "OK No quota."); return TRUE; } + if (ns->owner != client->user && !client->user->admin) { + mailbox_close(&box); + client_send_tagline(cmd, "NO Not showing other users' quota."); + return TRUE; + } /* send QUOTAROOT reply */ str = t_str_new(128); @@ -85,15 +111,16 @@ iter = quota_root_iter_init(box); while ((root = quota_root_iter_next(iter)) != NULL) { str_append_c(str, ' '); - imap_quote_append_string(str, quota_root_get_name(root), FALSE); + name = imap_quota_root_get_name(client->user, ns->owner, root); + imap_quote_append_string(str, name, FALSE); } quota_root_iter_deinit(&iter); - client_send_line(cmd->client, str_c(str)); + client_send_line(client, str_c(str)); /* send QUOTA reply for each quotaroot */ iter = quota_root_iter_init(box); while ((root = quota_root_iter_next(iter)) != NULL) - quota_send(cmd, root); + quota_send(cmd, ns->owner, root); quota_root_iter_deinit(&iter); mailbox_close(&box); @@ -103,8 +130,9 @@ static bool cmd_getquota(struct client_command_context *cmd) { - const char *root_name; + struct mail_user *owner = cmd->client->user; struct quota_root *root; + const char *root_name, *p; /* <quota root> */ if (!client_read_string_args(cmd, 1, &root_name)) @@ -116,12 +144,23 @@ } root = quota_root_lookup(cmd->client->user, root_name); + if (root == NULL && cmd->client->user->admin) { + /* we're an admin. see if there's a quota root for another + user. */ + p = strchr(root_name, QUOTA_USER_SEPARATOR); + if (p != NULL) { + owner = mail_user_find(cmd->client->user, + t_strdup_until(root_name, p)); + root = owner == NULL ? NULL : + quota_root_lookup(owner, p + 1); + } + } if (root == NULL) { client_send_tagline(cmd, "NO Quota root doesn't exist."); return TRUE; } - quota_send(cmd, root); + quota_send(cmd, owner, root); client_send_tagline(cmd, "OK Getquota completed."); return TRUE; }