Mercurial > dovecot > original-hg > dovecot-1.2
view src/plugins/quota/quota-dict.c @ 6429:65c69a53a7be HEAD
Replaced my Copyright notices. The year range always ends with 2007 now.
My name was replaced with "Dovecot authors". In many cases I didn't really
even own the copyright, so this is more correct.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 16 Sep 2007 14:34:22 +0300 |
parents | 6a64e64fa3a3 |
children | 414c9d631a81 |
line wrap: on
line source
/* Copyright (c) 2005-2007 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "dict.h" #include "quota-private.h" #include <stdlib.h> #define DICT_QUOTA_CURRENT_PATH DICT_PATH_PRIVATE"quota/" #define DICT_QUOTA_CURRENT_BYTES_PATH DICT_QUOTA_CURRENT_PATH"storage" #define DICT_QUOTA_CURRENT_COUNT_PATH DICT_QUOTA_CURRENT_PATH"messages" struct dict_quota_root { struct quota_root root; struct dict *dict; }; extern struct quota_backend quota_backend_dict; static struct quota_root *dict_quota_alloc(void) { struct dict_quota_root *root; root = i_new(struct dict_quota_root, 1); return &root->root; } static int dict_quota_init(struct quota_root *_root, const char *args) { struct dict_quota_root *root = (struct dict_quota_root *)_root; const char *username, *p; p = args == NULL ? NULL : strchr(args, ':'); if (p == NULL) { i_error("dict quota: URI missing from parameters"); return -1; } username = t_strdup_until(args, p); args = p+1; if (*username == '\0') username = getenv("USER"); if (getenv("DEBUG") != NULL) i_info("dict quota: user = %s, uri = %s", username, args); /* FIXME: we should use 64bit integer as datatype instead but before it can actually be used don't bother */ root->dict = dict_init(args, DICT_DATA_TYPE_STRING, username); return root->dict != NULL ? 0 : -1; } static void dict_quota_deinit(struct quota_root *_root) { struct dict_quota_root *root = (struct dict_quota_root *)_root; if (root->dict != NULL) dict_deinit(&root->dict); i_free(root); } static const char *const * dict_quota_root_get_resources(struct quota_root *root ATTR_UNUSED) { static const char *resources[] = { QUOTA_NAME_STORAGE_KILOBYTES, QUOTA_NAME_MESSAGES, NULL }; return resources; } static int dict_quota_count(struct dict_quota_root *root, bool want_bytes, uint64_t *value_r) { struct dict_transaction_context *dt; uint64_t bytes, count; if (quota_count(root->root.quota, &bytes, &count) < 0) return -1; t_push(); dt = dict_transaction_begin(root->dict); dict_set(dt, DICT_QUOTA_CURRENT_BYTES_PATH, dec2str(bytes)); dict_set(dt, DICT_QUOTA_CURRENT_COUNT_PATH, dec2str(count)); t_pop(); if (dict_transaction_commit(dt) < 0) i_error("dict_quota: Couldn't update quota"); *value_r = want_bytes ? bytes : count; return 1; } static int dict_quota_get_resource(struct quota_root *_root, const char *name, uint64_t *value_r, uint64_t *limit ATTR_UNUSED) { struct dict_quota_root *root = (struct dict_quota_root *)_root; const char *value; bool want_bytes; int ret; if (strcmp(name, QUOTA_NAME_STORAGE_BYTES) == 0) want_bytes = TRUE; else if (strcmp(name, QUOTA_NAME_MESSAGES) == 0) want_bytes = FALSE; else return 0; t_push(); ret = dict_lookup(root->dict, unsafe_data_stack_pool, want_bytes ? DICT_QUOTA_CURRENT_BYTES_PATH : DICT_QUOTA_CURRENT_COUNT_PATH, &value); if (ret < 0) *value_r = 0; else { long long tmp; /* recalculate quota if it's negative or if it wasn't found */ tmp = ret == 0 ? -1 : strtoll(value, NULL, 10); if (tmp < 0) ret = dict_quota_count(root, want_bytes, value_r); else *value_r = tmp; } t_pop(); return ret; } static int dict_quota_update(struct quota_root *_root, struct quota_transaction_context *ctx) { struct dict_quota_root *root = (struct dict_quota_root *) _root; struct dict_transaction_context *dt; dt = dict_transaction_begin(root->dict); if (ctx->recalculate) { dict_unset(dt, DICT_QUOTA_CURRENT_BYTES_PATH); dict_unset(dt, DICT_QUOTA_CURRENT_COUNT_PATH); } else { if (ctx->bytes_used != 0) { dict_atomic_inc(dt, DICT_QUOTA_CURRENT_BYTES_PATH, ctx->bytes_used); } if (ctx->count_used != 0) { dict_atomic_inc(dt, DICT_QUOTA_CURRENT_COUNT_PATH, ctx->count_used); } } if (dict_transaction_commit(dt) < 0) return -1; return 0; } struct quota_backend quota_backend_dict = { "dict", { dict_quota_alloc, dict_quota_init, dict_quota_deinit, NULL, NULL, dict_quota_root_get_resources, dict_quota_get_resource, dict_quota_update } };