From 25d59c107a7d58fb4016a5c297448b69777eaa63 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Wed, 13 May 2015 19:52:51 +0200
Subject: [PATCH] managesieve: Implemented support for reporting command
 statistics at disconnect.

---
 src/managesieve/cmd-deletescript.c   |  1 +
 src/managesieve/cmd-getscript.c      |  3 +++
 src/managesieve/cmd-putscript.c      |  8 ++++++++
 src/managesieve/cmd-renamescript.c   |  6 ++++--
 src/managesieve/managesieve-client.c | 22 +++++++++++++++++++---
 src/managesieve/managesieve-client.h |  9 +++++++++
 6 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/src/managesieve/cmd-deletescript.c b/src/managesieve/cmd-deletescript.c
index 23bdd1fcf..e019448a2 100644
--- a/src/managesieve/cmd-deletescript.c
+++ b/src/managesieve/cmd-deletescript.c
@@ -31,6 +31,7 @@ bool cmd_deletescript(struct client_command_context *cmd)
 	if ( sieve_script_delete(script, FALSE) < 0 ) {
 		client_send_storage_error(client, storage);
 	} else {
+		client->deleted_count++;
 		client_send_ok(client, "Deletescript completed.");
 	}
 
diff --git a/src/managesieve/cmd-getscript.c b/src/managesieve/cmd-getscript.c
index 1631a162e..460b1b276 100644
--- a/src/managesieve/cmd-getscript.c
+++ b/src/managesieve/cmd-getscript.c
@@ -40,6 +40,9 @@ static bool cmd_getscript_finish(struct cmd_getscript_context *ctx)
 		return TRUE;
 	}
 
+	client->get_count++;
+	client->get_bytes += ctx->script_size;
+
 	client_send_line(client, "");
 	client_send_ok(client, "Getscript completed.");
 	return TRUE;
diff --git a/src/managesieve/cmd-putscript.c b/src/managesieve/cmd-putscript.c
index 0c782d88f..738a4c2f0 100644
--- a/src/managesieve/cmd-putscript.c
+++ b/src/managesieve/cmd-putscript.c
@@ -249,6 +249,14 @@ static bool cmd_putscript_finish_parsing(struct client_command_context *cmd)
 
 			/* Report result to user */
 			if ( success ) {
+				if ( ctx->scriptname != NULL ) {
+					client->put_count++;
+					client->put_bytes += ctx->script_size;
+				} else {
+					client->check_count++;
+					client->check_bytes += ctx->script_size;
+				}
+
 				if ( sieve_get_warnings(ehandler) > 0 )
 					client_send_okresp(client, "WARNINGS", str_c(errors));
 				else {
diff --git a/src/managesieve/cmd-renamescript.c b/src/managesieve/cmd-renamescript.c
index 7e1d77e39..9b38380af 100644
--- a/src/managesieve/cmd-renamescript.c
+++ b/src/managesieve/cmd-renamescript.c
@@ -29,10 +29,12 @@ bool cmd_renamescript(struct client_command_context *cmd)
 		return TRUE;
 	}
 
-	if (sieve_script_rename(script, newname) < 0)
+	if (sieve_script_rename(script, newname) < 0) {
 		client_send_storage_error(client, storage);
-	else
+	} else {
+		client->renamed_count++;
 		client_send_ok(client, "Renamescript completed.");
+	}
 
 	sieve_script_unref(&script);
 	return TRUE;
diff --git a/src/managesieve/managesieve-client.c b/src/managesieve/managesieve-client.c
index 3b2f14e86..60c79e440 100644
--- a/src/managesieve/managesieve-client.c
+++ b/src/managesieve/managesieve-client.c
@@ -175,6 +175,14 @@ struct client *client_create
 static const char *client_stats(struct client *client)
 {
 	static struct var_expand_table static_tab[] = {
+		{ 't', NULL, "put_bytes" },
+		{ 'p', NULL, "put_count" },
+		{ 'b', NULL, "get_bytes" },
+		{ 'g', NULL, "get_count" },
+		{ 'v', NULL, "check_bytes" },
+		{ 'c', NULL, "check_count" },
+		{ 'd', NULL, "deleted_count" },
+		{ 'r', NULL, "renamed_count" },
 		{ 'i', NULL, "input" },
 		{ 'o', NULL, "output" },
 		{ '\0', NULL, "session" },
@@ -186,9 +194,17 @@ static const char *client_stats(struct client *client)
 	tab = t_malloc(sizeof(static_tab));
 	memcpy(tab, static_tab, sizeof(static_tab));
 
-	tab[0].value = dec2str(i_stream_get_absolute_offset(client->input));
-	tab[1].value = dec2str(client->output->offset);
-	tab[2].value = client->session_id;
+	tab[0].value = dec2str(client->put_bytes);
+	tab[1].value = dec2str(client->put_count);
+	tab[2].value = dec2str(client->get_bytes);
+	tab[3].value = dec2str(client->get_count);
+	tab[4].value = dec2str(client->check_bytes);
+	tab[5].value = dec2str(client->check_count);
+	tab[6].value = dec2str(client->deleted_count);
+	tab[7].value = dec2str(client->renamed_count);
+	tab[8].value = dec2str(i_stream_get_absolute_offset(client->input));
+	tab[9].value = dec2str(client->output->offset);
+	tab[10].value = client->session_id;
 
 	str = t_str_new(128);
 	var_expand(str, client->set->managesieve_logout_format, tab);
diff --git a/src/managesieve/managesieve-client.h b/src/managesieve/managesieve-client.h
index 33cc6d0a3..3ff486d45 100644
--- a/src/managesieve/managesieve-client.h
+++ b/src/managesieve/managesieve-client.h
@@ -57,6 +57,15 @@ struct client {
 	struct managesieve_parser *parser;
 	struct client_command_context cmd;
 
+	uoff_t put_bytes;
+	uoff_t get_bytes;
+	uoff_t check_bytes;
+	unsigned int put_count;
+	unsigned int get_count;
+	unsigned int check_count;
+	unsigned int deleted_count;
+	unsigned int renamed_count;
+
 	unsigned int disconnected:1;
 	unsigned int destroyed:1;
 	unsigned int command_pending:1;
-- 
GitLab