quota.c revision 26a8b7deb3a5b6f26f9c4d71538e1248f680e4be
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (C) 2005 Timo Sirainen */
6634e45500e81cfa36932203ee69c81745efd3e6Timo Sirainen unsigned int i;
60ba197d17023594231d9805d889817782e41859Timo Sirainenunsigned int quota_module_id = 0;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenextern struct quota_backend quota_backend_dict;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenextern struct quota_backend quota_backend_dirsize;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenextern struct quota_backend quota_backend_maildir;
0ebeb1831a56e020b0958ed1ced50e86ee9347ecTimo Sirainenstatic const struct quota_backend *quota_backends[] = {
0ebeb1831a56e020b0958ed1ced50e86ee9347ecTimo Sirainen#define QUOTA_CLASS_COUNT (sizeof(quota_backends)/sizeof(quota_backends[0]))
0ebeb1831a56e020b0958ed1ced50e86ee9347ecTimo Sirainenstatic int quota_default_test_alloc(struct quota_transaction_context *ctx,
0ebeb1831a56e020b0958ed1ced50e86ee9347ecTimo Sirainen ARRAY_CREATE("a->storages, default_pool, 8);
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen root = array_idx_modifiable("a->roots, 0);
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstatic const struct quota_backend *quota_backend_find(const char *name)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen unsigned int i;
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen for (i = 0; i < QUOTA_CLASS_COUNT; i++) {
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (strcmp(quota_backends[i]->name, name) == 0)
4ba3717a04823875c2a1d60ff9dc8177ae033d12Timo Sirainenstruct quota_root *quota_root_init(struct quota *quota, const char *root_def)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen /* <backend>[:<quota root name>[:<backend args>]] */
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen i_fatal("Unknown quota backend: %s", backend_name);
5455a917515f774fcaad35558f149536b796b531Teemu Huovila root->pool = pool_alloconly_create("quota root", 512);
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen /* save root's name */
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen root->name = p_strdup_until(root->pool, args, p);
4c61d6b6ad6173f06563c2cee9bd813c59277dd2Timo Sirainen array_create(&root->quota_module_contexts, default_pool,
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen sizeof(void *), 5);
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenvoid quota_root_deinit(struct quota_root *root)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen unsigned int i, count;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen roots = array_get(&root->quota->roots, &count);
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen for (i = 0; i < count; i++) {
4ef1f9f3293965734e6e3c38c191ceb2246a721fTeemu Huovilastatic struct quota_rule *
4ef1f9f3293965734e6e3c38c191ceb2246a721fTeemu Huovilaquota_root_rule_find(struct quota_root *root, const char *name)
4ef1f9f3293965734e6e3c38c191ceb2246a721fTeemu Huovila unsigned int i, count;
4ef1f9f3293965734e6e3c38c191ceb2246a721fTeemu Huovila rules = array_get_modifiable(&root->rules, &count);
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainen for (i = 0; i < count; i++) {
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainenint quota_root_add_rule(struct quota_root *root, const char *rule_def,
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainen const char **error_r)
4ef1f9f3293965734e6e3c38c191ceb2246a721fTeemu Huovila const char **args;
4ef1f9f3293965734e6e3c38c191ceb2246a721fTeemu Huovila /* <mailbox name>:<quota limits> */
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainen if (strcmp(*args, RULE_NAME_ALL_MAILBOXES) == 0)
4ef1f9f3293965734e6e3c38c191ceb2246a721fTeemu Huovila rule->mailbox_name = p_strdup(root->pool, *args);
0ebeb1831a56e020b0958ed1ced50e86ee9347ecTimo Sirainen rule->bytes_limit = strtoll(*args + 8, NULL, 10) * 1024;
0ebeb1831a56e020b0958ed1ced50e86ee9347ecTimo Sirainen rule->count_limit = strtoll(*args + 9, NULL, 10);
4ef1f9f3293965734e6e3c38c191ceb2246a721fTeemu Huovilastatic bool quota_root_get_rule_limits(struct quota_root *root,
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainen /* if default rule limits are 0, this rule applies only to specific
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainen rule = quota_root_rule_find(root, mailbox_name);
09aed882b99e865ff6d7140ae2f77a42c9e7d1a7Teemu Huovila *bytes_limit_r = bytes_limit <= 0 ? 0 : bytes_limit;
09aed882b99e865ff6d7140ae2f77a42c9e7d1a7Teemu Huovila *count_limit_r = count_limit <= 0 ? 0 : count_limit;
09aed882b99e865ff6d7140ae2f77a42c9e7d1a7Teemu Huovilavoid quota_add_user_storage(struct quota *quota, struct mail_storage *storage)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen unsigned int i, j, count;
09aed882b99e865ff6d7140ae2f77a42c9e7d1a7Teemu Huovila /* @UNSAFE: get different backends into one array */
09aed882b99e865ff6d7140ae2f77a42c9e7d1a7Teemu Huovila backends = t_new(struct quota_backend *, count + 1);
09aed882b99e865ff6d7140ae2f77a42c9e7d1a7Teemu Huovila for (i = 0; i < count; i++) {
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (backends[j]->name == roots[i]->backend.name)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenvoid quota_remove_user_storage(struct quota *quota,
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen unsigned int i, count;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen storages = array_get("a->storages, &count);
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen for (i = 0; i < count; i++) {
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainenquota_root_iter_init(struct quota *quota, struct mailbox *box)
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainenstruct quota_root *quota_root_iter_next(struct quota_root_iter *iter)
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainen struct quota_root *const *roots, *root = NULL;
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainen unsigned int count;
ebcd7cf40e53c2bbc98f7f686e206cda5c0e3111Timo Sirainen roots = array_get(&iter->quota->roots, &count);
ebcd7cf40e53c2bbc98f7f686e206cda5c0e3111Timo Sirainenvoid quota_root_iter_deinit(struct quota_root_iter *iter)
ebcd7cf40e53c2bbc98f7f686e206cda5c0e3111Timo Sirainenstruct quota_root *quota_root_lookup(struct quota *quota, const char *name)
60ba197d17023594231d9805d889817782e41859Timo Sirainen unsigned int i, count;
60ba197d17023594231d9805d889817782e41859Timo Sirainen for (i = 0; i < count; i++) {
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainenconst char *quota_root_get_name(struct quota_root *root)
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainenconst char *const *quota_root_get_resources(struct quota_root *root)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenint quota_get_resource(struct quota_root *root, const char *mailbox_name,
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen const char *name, uint64_t *value_r, uint64_t *limit_r)
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainen (void)quota_root_get_rule_limits(root, mailbox_name,
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen else if (strcmp(name, QUOTA_NAME_MESSAGES) == 0)
6634e45500e81cfa36932203ee69c81745efd3e6Timo Sirainen ret = root->backend.v.get_resource(root, name, value_r, limit_r);
6634e45500e81cfa36932203ee69c81745efd3e6Timo Sirainenint quota_set_resource(struct quota_root *root __attr_unused__,
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen uint64_t value __attr_unused__, const char **error_r)
dbf26a3ea43cd79fe88f01ec99c7d9440679b996Timo Sirainen /* the quota information comes from userdb (or even config file),
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen so there's really no way to support this until some major changes
09aed882b99e865ff6d7140ae2f77a42c9e7d1a7Teemu Huovilastruct quota_transaction_context *quota_transaction_begin(struct quota *quota,
eeb03434472130f9631f164440566fd8d09e6380Timo Sirainen unsigned int i, count;
6634e45500e81cfa36932203ee69c81745efd3e6Timo Sirainen ctx = i_new(struct quota_transaction_context, 1);
for (i = 0; i < count; i++) {
if (ret > 0) {
} else if (ret < 0) {
if (ret > 0) {
} else if (ret < 0) {
return ctx;
unsigned int i, count;
int ret = 0;
for (i = 0; i < count; i++) {
return ret;
int ret;
if (ret <= 0)
return ret;
unsigned int i, count;
for (i = 0; i < count; i++) {