#include "net.h"
#include "write-full.h"
#include "eacces-error.h"
+#include "dict.h"
#include "mailbox-list-private.h"
#include "quota-private.h"
#include "quota-fs.h"
"Quota exceeded (mailbox for user is full)"
#define RULE_NAME_DEFAULT_FORCE "*"
#define RULE_NAME_DEFAULT_NONFORCE "?"
+#define QUOTA_LIMIT_SET_PATH DICT_PATH_PRIVATE"quota/limit/"
struct quota_root_iter {
struct quota *quota;
return 0;
}
+static int
+quota_root_parse_set(struct mail_user *user, const char *root_name,
+ struct quota_root_settings *root_set,
+ const char **error_r)
+{
+ const char *name, *value;
+
+ name = t_strconcat(root_name, "_set", NULL);
+ value = mail_user_plugin_getenv(user, name);
+ if (value == NULL)
+ return 0;
+
+ if (strncmp(value, "dict:", 5) != 0) {
+ *error_r = t_strdup_printf("%s supports only dict backend", name);
+ return -1;
+ }
+ root_set->limit_set = p_strdup(root_set->set->pool, value+5);
+ return 0;
+}
+
static int
quota_root_settings_init(struct quota_settings *quota_set, const char *root_def,
struct quota_root_settings **set_r,
return -1;
if (quota_root_parse_grace(user, root_name, root_set, error_r) < 0)
return -1;
+ if (quota_root_parse_set(user, root_name, root_set, error_r) < 0)
+ return -1;
return 0;
}
{
pool_t pool = root->pool;
+ if (root->limit_set_dict != NULL)
+ dict_deinit(&root->limit_set_dict);
root->backend.v.deinit(root);
pool_unref(&pool);
}
return *limit_r == 0 ? 0 : 1;
}
-int quota_set_resource(struct quota_root *root ATTR_UNUSED,
- const char *name ATTR_UNUSED,
- uint64_t value ATTR_UNUSED, const char **error_r)
+int quota_set_resource(struct quota_root *root, const char *name,
+ uint64_t value, const char **error_r)
{
- /* the quota information comes from userdb (or even config file),
- so there's really no way to support this until some major changes
- are done */
- *error_r = MAIL_ERRSTR_NO_PERMISSION;
- return -1;
+ struct dict_transaction_context *trans;
+ const char *key;
+
+ if (root->set->limit_set == NULL) {
+ *error_r = MAIL_ERRSTR_NO_PERMISSION;
+ return -1;
+ }
+ if (strcasecmp(name, QUOTA_NAME_STORAGE_KILOBYTES) == 0)
+ key = "storage";
+ else if (strcasecmp(name, QUOTA_NAME_STORAGE_BYTES) == 0)
+ key = "bytes";
+ else if (strcasecmp(name, QUOTA_NAME_MESSAGES) == 0)
+ key = "messages";
+ else {
+ *error_r = t_strdup_printf("Unsupported resource name: %s", name);
+ return -1;
+ }
+
+ if (root->limit_set_dict == NULL) {
+ if (dict_init(root->set->limit_set, DICT_DATA_TYPE_STRING,
+ root->quota->user->username,
+ root->quota->user->set->base_dir,
+ &root->limit_set_dict, error_r) < 0)
+ return -1;
+ }
+
+ trans = dict_transaction_begin(root->limit_set_dict);
+ key = t_strdup_printf(QUOTA_LIMIT_SET_PATH"%s", key);
+ dict_set(trans, key, dec2str(value));
+ if (dict_transaction_commit(&trans) < 0) {
+ *error_r = "Internal quota limit update error";
+ return -1;
+ }
+ return 0;
}
struct quota_transaction_context *quota_transaction_begin(struct mailbox *box)