quota-status.c revision f6008a666d9c3df66fd8a437369133e8519b4e24
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2013-2016 Dovecot authors, see the included COPYING file */
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "lib.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "ostream.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "connection.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "restrict-access.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "master-service.h"
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen#include "master-service-settings.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "mail-namespace.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "mail-storage.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "mail-storage-settings.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "mail-storage-service.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "quota-private.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "quota-plugin.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenenum quota_protocol {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen QUOTA_PROTOCOL_UNKNOWN = 0,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen QUOTA_PROTOCOL_POSTFIX
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen};
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstruct quota_client {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct connection conn;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen char *recipient;
f8b73b7a49b4471bdb92daa9284f181322709011Timo Sirainen uoff_t size;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen};
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic enum quota_protocol protocol;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic struct mail_storage_service_ctx *storage_service;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic struct connection_list *clients;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainenstatic char *nouser_reply;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_connected(struct master_service_connection *conn)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_client *client;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen client = i_new(struct quota_client, 1);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen connection_init_server(clients, &client->conn,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen "(quota client)", conn->fd, conn->fd);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen master_service_client_connection_accept(conn);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_reset(struct quota_client *client)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen i_free_and_null(client->recipient);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
f8b73b7a49b4471bdb92daa9284f181322709011Timo Sirainenstatic int
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainenquota_check(struct mail_user *user, uoff_t mail_size,
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen const char **error_r, bool *too_large_r)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_user *quser = QUOTA_USER_CONTEXT(user);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mail_namespace *ns;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mailbox *box;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_transaction_context *ctx;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen int ret;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (quser == NULL) {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen /* no quota for user */
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return 1;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen ns = mail_namespace_find_inbox(user->namespaces);
e66cd209fcab4817d2234d0121b404925dc60034Timo Sirainen box = mailbox_alloc(ns->list, "INBOX", MAILBOX_FLAG_POST_SESSION);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen ctx = quota_transaction_begin(box);
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen ret = quota_test_alloc(ctx, I_MAX(1, mail_size), too_large_r);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen quota_transaction_rollback(&ctx);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen mailbox_free(&box);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (ret < 0)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen *error_r = "Internal quota calculation error";
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen else if (ret == 0)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen *error_r = quser->quota->set->quota_exceeded_msg;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return ret;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_handle_request(struct quota_client *client)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mail_storage_service_input input;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mail_storage_service_user *service_user;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mail_user *user;
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen const char *value = NULL, *error;
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen bool too_large;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen int ret;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (client->recipient == NULL) {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen o_stream_send_str(client->conn.output, "action=DUNNO\n\n");
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen memset(&input, 0, sizeof(input));
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen input.username = client->recipient;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen ret = mail_storage_service_lookup_next(storage_service, &input,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen &service_user, &user, &error);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen restrict_access_allow_coredumps(TRUE);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (ret == 0) {
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen value = nouser_reply;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen } else if (ret > 0) {
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen if ((ret = quota_check(user, client->size, &error, &too_large)) > 0) {
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen /* under quota */
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen value = mail_user_plugin_getenv(user, "quota_status_success");
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen if (value == NULL)
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen value = "OK";
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen } else if (ret == 0) {
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen if (too_large) {
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen /* even over maximum quota */
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen value = mail_user_plugin_getenv(user, "quota_status_toolarge");
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen }
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen if (value == NULL)
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen value = mail_user_plugin_getenv(user, "quota_status_overquota");
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen if (value == NULL)
cf0184bf140bec4262fb0434bbdc10cf2c3efc1aTimo Sirainen value = t_strdup_printf("554 5.2.2 %s", error);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
b8164b588348c124acc469841ec7a5ca93a8efcdTimo Sirainen value = t_strdup(value); /* user's pool is being freed */
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen mail_user_unref(&user);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen mail_storage_service_user_free(&service_user);
f6008a666d9c3df66fd8a437369133e8519b4e24Timo Sirainen } else {
f6008a666d9c3df66fd8a437369133e8519b4e24Timo Sirainen i_error("Failed to lookup user %s: %s", input.username, error);
f6008a666d9c3df66fd8a437369133e8519b4e24Timo Sirainen error = "Temporary internal error";
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
f6008a666d9c3df66fd8a437369133e8519b4e24Timo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (ret < 0) {
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen /* temporary failure */
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen o_stream_send_str(client->conn.output, t_strdup_printf(
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen "action=DEFER_IF_PERMIT %s\n\n", error));
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen } else {
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen o_stream_send_str(client->conn.output,
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen t_strdup_printf("action=%s\n\n", value));
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic int client_input_line(struct connection *conn, const char *line)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_client *client = (struct quota_client *)conn;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (*line == '\0') {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen o_stream_cork(conn->output);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen client_handle_request(client);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen o_stream_uncork(conn->output);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen client_reset(client);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return 1;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (client->recipient == NULL &&
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen strncmp(line, "recipient=", 10) == 0)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen client->recipient = i_strdup(line + 10);
f8b73b7a49b4471bdb92daa9284f181322709011Timo Sirainen else if (strncmp(line, "size=", 5) == 0) {
f8b73b7a49b4471bdb92daa9284f181322709011Timo Sirainen if (str_to_uoff(line+5, &client->size) < 0)
f8b73b7a49b4471bdb92daa9284f181322709011Timo Sirainen client->size = 0;
f8b73b7a49b4471bdb92daa9284f181322709011Timo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return 1;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_destroy(struct connection *conn)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_client *client = (struct quota_client *)conn;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen connection_deinit(&client->conn);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen client_reset(client);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen i_free(client);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen master_service_client_connection_destroyed(master_service);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic struct connection_settings client_set = {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen .input_max_size = (size_t)-1,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen .output_max_size = (size_t)-1,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen .client = FALSE
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen};
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic const struct connection_vfuncs client_vfuncs = {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen .destroy = client_destroy,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen .input_line = client_input_line
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen};
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void main_preinit(void)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen restrict_access_by_env(NULL, FALSE);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen restrict_access_allow_coredumps(TRUE);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void main_init(void)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen struct mail_storage_service_input input;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen const struct setting_parser_info *user_info;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen const struct setting_parser_context *set_parser;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen const struct mail_user_settings *user_set;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen const char *value, *error;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen pool_t pool;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen clients = connection_list_init(&client_set, &client_vfuncs);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen storage_service = mail_storage_service_init(master_service, NULL,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP |
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP |
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS |
7f5c66ef0fbdca9dc1657490099bdb87922099a4Timo Sirainen MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR);
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen memset(&input, 0, sizeof(input));
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen input.service = "quota-status";
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen input.module = "mail";
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen input.username = "";
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen pool = pool_alloconly_create("service all settings", 4096);
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen if (mail_storage_service_read_settings(storage_service, &input, pool,
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen &user_info, &set_parser,
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen &error) < 0)
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen i_fatal("%s", error);
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen user_set = master_service_settings_parser_get_others(master_service,
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen set_parser)[0];
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen value = mail_user_set_plugin_getenv(user_set, "quota_status_nouser");
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen nouser_reply = value != NULL ? i_strdup(value) :
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen i_strdup("REJECT Unknown user");
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen pool_unref(&pool);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void main_deinit(void)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen i_free(nouser_reply);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen connection_list_deinit(&clients);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen mail_storage_service_deinit(&storage_service);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenint main(int argc, char *argv[])
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c5acac1fd44571aabefc1b4db291488b87f822a0Timo Sirainen enum master_service_flags service_flags =
c5acac1fd44571aabefc1b4db291488b87f822a0Timo Sirainen MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen int c;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen protocol = QUOTA_PROTOCOL_UNKNOWN;
c5acac1fd44571aabefc1b4db291488b87f822a0Timo Sirainen master_service = master_service_init("quota-status", service_flags,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen &argc, &argv, "p:");
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen while ((c = master_getopt(master_service)) > 0) {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen switch (c) {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen case 'p':
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (strcmp(optarg, "postfix") == 0)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen protocol = QUOTA_PROTOCOL_POSTFIX;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen else
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen i_fatal("Unknown -p parameter: '%s'", optarg);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen break;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen default:
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return FATAL_DEFAULT;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (protocol == QUOTA_PROTOCOL_UNKNOWN)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen i_fatal("Missing -p parameter");
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c8fff8f35c459f8577694b585183228ba1631fe2Timo Sirainen master_service_init_log(master_service, "quota-status: ");
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen main_preinit();
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen main_init();
d6b3cfd855c0eebed68be50d3111de1b5a6afeb0Timo Sirainen master_service_init_finish(master_service);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen master_service_run(master_service, client_connected);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen main_deinit();
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen master_service_deinit(&master_service);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return 0;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}