root->backend = *root_set->backend;
root->bytes_limit = root_set->default_rule.bytes_limit;
root->count_limit = root_set->default_rule.count_limit;
+ p_array_init(&root->namespaces, root->pool, 4);
array_create(&root->quota_module_contexts, root->pool,
sizeof(void *), 10);
i_array_init("a->roots, 8);
root_sets = array_get("a_set->root_sets, &count);
- i_array_init("a->namespaces, count);
for (i = 0; i < count; i++) {
ret = quota_root_init(root_sets[i], quota, &root, &error);
if (ret < 0) {
*_quota = NULL;
array_free("a->roots);
- array_free("a->namespaces);
event_unref("a->event);
i_free(quota);
}
}
static bool
-quota_is_duplicate_namespace(struct quota *quota, struct mail_namespace *ns)
+quota_is_duplicate_namespace(struct quota_root *root, struct mail_namespace *ns)
{
struct mail_namespace *const *namespaces;
unsigned int i, count;
MAILBOX_LIST_PATH_TYPE_MAILBOX, &path))
path = NULL;
- namespaces = array_get("a->namespaces, &count);
+ namespaces = array_get(&root->namespaces, &count);
for (i = 0; i < count; i++) {
/* Count namespace aliases only once. Don't rely only on
non-empty alias_for, because the alias might have been
an alternative would be to do a bit larger change so
namespaces wouldn't be added until
mail_namespaces_created() hook is called */
- i_assert(quota->unwanted_ns == NULL);
- quota->unwanted_ns = namespaces[i];
+ i_assert(root->unwanted_ns == NULL);
+ root->unwanted_ns = namespaces[i];
return FALSE;
}
}
void quota_add_user_namespace(struct quota *quota, struct mail_namespace *ns)
{
- struct quota_root *const *roots;
- struct quota_backend **backends;
- unsigned int i, j, count;
-
- /* first check if there already exists a namespace with the exact same
- path. we don't want to count them twice. */
- if (quota_is_duplicate_namespace(quota, ns))
- return;
+ struct quota_root *root;
- array_push_back("a->namespaces, &ns);
+ array_foreach_elem("a->roots, root) {
+ /* first check if there already exists a namespace with the
+ exact same path. we don't want to count them twice. */
+ if (quota_is_duplicate_namespace(root, ns))
+ continue;
- roots = array_get("a->roots, &count);
- /* @UNSAFE: get different backends into one array */
- backends = t_new(struct quota_backend *, count + 1);
- for (i = 0; i < count; i++) {
- for (j = 0; backends[j] != NULL; j++) {
- if (backends[j]->name == roots[i]->backend.name)
- break;
- }
- if (backends[j] == NULL)
- backends[j] = &roots[i]->backend;
- }
+ array_push_back(&root->namespaces, &ns);
- for (i = 0; backends[i] != NULL; i++) {
- if (backends[i]->v.namespace_added != NULL)
- backends[i]->v.namespace_added(quota, ns);
+ if (root->backend.v.namespace_added != NULL)
+ root->backend.v.namespace_added(quota, ns);
}
}
void quota_remove_user_namespace(struct mail_namespace *ns)
{
struct quota *quota;
+ struct quota_root *root;
struct mail_namespace *const *namespaces;
unsigned int i, count;
return;
}
- namespaces = array_get("a->namespaces, &count);
- for (i = 0; i < count; i++) {
- if (namespaces[i] == ns) {
- array_delete("a->namespaces, i, 1);
- break;
+ array_foreach_elem("a->roots, root) {
+ namespaces = array_get(&root->namespaces, &count);
+ for (i = 0; i < count; i++) {
+ if (namespaces[i] == ns) {
+ array_delete(&root->namespaces, i, 1);
+ break;
+ }
}
}
}
if (mailbox_list_get_storage(&list, &vname, 0, &storage) == 0 &&
(storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NOQUOTA) != 0)
return FALSE;
- if (root->quota->unwanted_ns == ns)
+ if (root->unwanted_ns == ns)
return FALSE;
if (root->ns_prefix != NULL) {