[evolution-mapi] Bug #601483 - Support for quota message service
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Bug #601483 - Support for quota message service
- Date: Wed, 1 Feb 2012 19:36:35 +0000 (UTC)
commit 3e7de4893a369282903bcd3e86f57f22b0c281f5
Author: Milan Crha <mcrha redhat com>
Date: Wed Feb 1 20:36:10 2012 +0100
Bug #601483 - Support for quota message service
src/camel/camel-mapi-folder.c | 50 +++++++++++
src/camel/camel-mapi-store.c | 35 ++++++++-
src/libexchangemapi/e-mapi-connection.c | 136 ++++++++++++++++++++++++++++---
src/libexchangemapi/e-mapi-connection.h | 8 ++
4 files changed, 218 insertions(+), 11 deletions(-)
---
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index 819475c..b9c3330 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -1855,6 +1855,55 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
return success;
}
+static CamelFolderQuotaInfo *
+mapi_folder_get_quota_info_sync (CamelFolder *folder,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelMapiStore *mapi_store;
+ CamelFolderQuotaInfo *quota_info = NULL;
+ EMapiConnection *conn;
+ uint64_t current_size = -1, receive_quota = -1, send_quota = -1;
+
+ g_return_val_if_fail (folder != NULL, NULL);
+ g_return_val_if_fail (CAMEL_IS_MAPI_FOLDER (folder), NULL);
+
+ mapi_store = CAMEL_MAPI_STORE (camel_folder_get_parent_store (folder));
+ g_return_val_if_fail (mapi_store != NULL, NULL);
+
+ /* check for offline operation */
+ if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)))
+ return NULL;
+
+ conn = camel_mapi_store_get_connection (mapi_store);
+ if (conn && e_mapi_connection_get_store_quotas (
+ conn, NULL,
+ ¤t_size, &receive_quota, &send_quota,
+ cancellable, error)) {
+ if (current_size != -1) {
+ if (receive_quota != -1) {
+ quota_info = camel_folder_quota_info_new (_("Receive quota"), current_size, receive_quota);
+ }
+
+ if (send_quota != -1) {
+ CamelFolderQuotaInfo *qi;
+
+ qi = camel_folder_quota_info_new (_("Send quota"), current_size, send_quota);
+ if (quota_info)
+ quota_info->next = qi;
+ else
+ quota_info = qi;
+ }
+ }
+ }
+
+ if (!quota_info)
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("No quota information available"));
+
+ return quota_info;
+}
+
static void
camel_mapi_folder_class_init (CamelMapiFolderClass *class)
{
@@ -1881,6 +1930,7 @@ camel_mapi_folder_class_init (CamelMapiFolderClass *class)
folder_class->refresh_info_sync = mapi_folder_refresh_info_sync;
folder_class->synchronize_sync = mapi_folder_synchronize_sync;
folder_class->transfer_messages_to_sync = mapi_folder_transfer_messages_to_sync;
+ folder_class->get_quota_info_sync = mapi_folder_get_quota_info_sync;
}
static void
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index 826ddbe..62f1815 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -2042,6 +2042,7 @@ mapi_connect_sync (CamelService *service,
CamelMapiStore *store = CAMEL_MAPI_STORE (service);
CamelServiceConnectionStatus status;
CamelSession *session;
+ uint64_t current_size = -1, receive_quota = -1, send_quota = -1;
gchar *name;
if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
@@ -2066,12 +2067,12 @@ mapi_connect_sync (CamelService *service,
name = camel_service_get_name (service, TRUE);
camel_operation_push_message (cancellable, _("Connecting to '%s'"), name);
- g_free (name);
if (!camel_session_authenticate_sync (session, service, NULL, cancellable, error)) {
camel_operation_pop_message (cancellable);
camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
camel_service_disconnect_sync (service, TRUE, NULL);
+ g_free (name);
return FALSE;
}
@@ -2082,6 +2083,38 @@ mapi_connect_sync (CamelService *service,
camel_store_summary_save (store->summary);
+ if (e_mapi_connection_get_store_quotas (
+ store->priv->conn, NULL,
+ ¤t_size, &receive_quota, &send_quota,
+ cancellable, NULL)) {
+
+ if (current_size != -1) {
+ gchar *msg = NULL;
+
+ /* warn/alert when the last 1% lefts from the size quota */
+ if (send_quota != -1 && current_size * 0.95 >= send_quota) {
+ if (send_quota != -1 && current_size >= send_quota) {
+ msg = g_strdup_printf (_("Mailbox '%s' is full, no new messages will be received or sent."), name);
+ } else {
+ msg = g_strdup_printf (_("Mailbox '%s' is near its size limit, message send will be disabled soon."), name);
+ }
+ } else if (receive_quota != -1 && current_size * 0.95 >= receive_quota) {
+ if (current_size >= receive_quota) {
+ msg = g_strdup_printf (_("Mailbox '%s' is full, no new messages will be received."), name);
+ } else {
+ msg = g_strdup_printf (_("Mailbox '%s' is near its size limit."), name);
+ }
+ }
+
+ if (msg) {
+ camel_session_alert_user (session, CAMEL_SESSION_ALERT_WARNING, msg, NULL);
+ g_free (msg);
+ }
+ }
+ }
+
+ g_free (name);
+
camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
return TRUE;
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index 3063e53..6e42c3b 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -130,6 +130,7 @@ make_mapi_error (GError **perror, const gchar *context, enum MAPISTATUS mapi_sta
err (MAPI_E_END_OF_SESSION, _("End of session"));
err (MAPI_E_NOT_INITIALIZED, _("MAPI is not initialized or connected"));
err (MAPI_E_NO_ACCESS, _("Permission denied"));
+ err (ecShutoffQuotaExceeded, _("Mailbox quota exceeded"));
#undef err
@@ -891,6 +892,105 @@ e_mapi_connection_peek_store (EMapiConnection *conn,
return TRUE;
}
+/* sets quotas and current_size to -1 when not available, but still can return TRUE */
+gboolean
+e_mapi_connection_get_store_quotas (EMapiConnection *conn,
+ mapi_object_t *obj_store, /* can be NULL, for mailbox store */
+ uint64_t *current_size, /* out */
+ uint64_t *receive_quota, /* out */
+ uint64_t *send_quota, /* out */
+ GCancellable *cancellable,
+ GError **perror)
+{
+ enum MAPISTATUS ms = MAPI_E_RESERVED;
+ TALLOC_CTX *mem_ctx;
+ struct SPropTagArray *spropTagArray = NULL;
+ struct SPropValue *lpProps = NULL;
+ mapi_object_t *use_store;
+
+ CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+ e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+ e_return_val_mapi_error_if_fail (current_size != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+ e_return_val_mapi_error_if_fail (receive_quota != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+ e_return_val_mapi_error_if_fail (send_quota != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+
+ use_store = obj_store;
+ if (!use_store)
+ use_store = &priv->msg_store;
+
+ *current_size = -1;
+ *receive_quota = -1;
+ *send_quota = -1;
+
+ LOCK ();
+ mem_ctx = talloc_new (priv->session);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
+ ms = MAPI_E_USER_CANCEL;
+ goto cleanup;
+ }
+
+ spropTagArray = set_SPropTagArray (mem_ctx, 4,
+ PidTagMessageSize,
+ PidTagMessageSizeExtended,
+ PidTagProhibitReceiveQuota,
+ PidTagProhibitSendQuota);
+
+ if (spropTagArray && spropTagArray->cValues) {
+ uint32_t prop_count = 0;
+ const uint32_t *pmessage_size, *preceive_quota, *psend_quota;
+ const uint64_t *pmessage_size_ex;
+
+ ms = GetProps (use_store, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, spropTagArray, &lpProps, &prop_count);
+ if (ms != MAPI_E_SUCCESS) {
+ make_mapi_error (perror, "GetProps", ms);
+ goto cleanup;
+ } else if (!lpProps) {
+ ms = MAPI_E_CALL_FAILED;
+ make_mapi_error (perror, "GetProps", ms);
+ goto cleanup;
+ }
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
+ ms = MAPI_E_USER_CANCEL;
+ goto cleanup;
+ }
+
+ pmessage_size = e_mapi_util_find_SPropVal_array_propval (lpProps, PidTagMessageSize);
+ pmessage_size_ex = e_mapi_util_find_SPropVal_array_propval (lpProps, PidTagMessageSizeExtended);
+ preceive_quota = e_mapi_util_find_SPropVal_array_propval (lpProps, PidTagProhibitReceiveQuota);
+ psend_quota = e_mapi_util_find_SPropVal_array_propval (lpProps, PidTagProhibitSendQuota);
+
+ if (pmessage_size && *pmessage_size != -1)
+ *current_size = *pmessage_size;
+ else if (pmessage_size_ex && *pmessage_size_ex)
+ *current_size = *pmessage_size_ex;
+
+ if (*current_size != -1) {
+ if (preceive_quota && *preceive_quota != -1) {
+ *receive_quota = *preceive_quota;
+ *receive_quota *= 1024;
+ }
+
+ if (psend_quota && *psend_quota != -1) {
+ *send_quota = *psend_quota;
+ *send_quota *= 1024;
+ }
+ }
+ } else {
+ ms = MAPI_E_NOT_ENOUGH_RESOURCES;
+ make_mapi_error (perror, "set_SPropTagArray", ms);
+ }
+
+ cleanup:
+ talloc_free (spropTagArray);
+ talloc_free (lpProps);
+ talloc_free (mem_ctx);
+ UNLOCK();
+
+ return ms == MAPI_E_SUCCESS;
+}
+
gboolean
e_mapi_connection_open_default_folder (EMapiConnection *conn,
uint32_t olFolderIdentifier,
@@ -1140,6 +1240,7 @@ e_mapi_connection_get_folder_properties (EMapiConnection *conn,
TALLOC_CTX *mem_ctx;
struct SPropTagArray *spropTagArray = NULL;
struct mapi_SPropValue_array *properties = NULL;
+ struct SPropValue *lpProps = NULL;
gboolean res = FALSE;
CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
@@ -1165,14 +1266,11 @@ e_mapi_connection_get_folder_properties (EMapiConnection *conn,
properties = talloc_zero (mem_ctx, struct mapi_SPropValue_array);
if (spropTagArray && spropTagArray->cValues) {
- struct SPropValue *lpProps;
uint32_t prop_count = 0, k, ll;
EResolveNamedIDsData *named_ids_list = NULL;
guint named_ids_len = 0;
GHashTable *replace_hash = NULL;
- lpProps = talloc_zero (mem_ctx, struct SPropValue);
-
for (k = 0; k < spropTagArray->cValues; k++) {
uint32_t proptag = spropTagArray->aulPropTag[k];
@@ -1217,6 +1315,11 @@ e_mapi_connection_get_folder_properties (EMapiConnection *conn,
make_mapi_error (perror, "GetProps", ms);
g_free (named_ids_list);
goto cleanup;
+ } else if (!lpProps) {
+ ms = MAPI_E_CALL_FAILED;
+ make_mapi_error (perror, "GetProps", ms);
+ g_free (named_ids_list);
+ goto cleanup;
}
if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
@@ -1263,6 +1366,7 @@ e_mapi_connection_get_folder_properties (EMapiConnection *conn,
cleanup:
talloc_free (spropTagArray);
talloc_free (properties);
+ talloc_free (lpProps);
talloc_free (mem_ctx);
UNLOCK();
@@ -2895,6 +2999,8 @@ e_mapi_connection_transfer_summary (EMapiConnection *conn,
ms = MAPI_E_USER_CANCEL;
e_mapi_object_free (object);
mapi_object_release (&obj_message);
+ talloc_free (lpProps);
+ talloc_free (tags);
goto cleanup;
}
@@ -2917,11 +3023,14 @@ e_mapi_connection_transfer_summary (EMapiConnection *conn,
if (ms != MAPI_E_SUCCESS) {
make_mapi_error (perror, "transfer_object", ms);
mapi_object_release (&obj_message);
+ talloc_free (lpProps);
+ talloc_free (tags);
goto cleanup;
}
}
mapi_object_release (&obj_message);
+ talloc_free (lpProps);
talloc_free (tags);
}
@@ -5522,7 +5631,7 @@ mapi_get_ren_additional_fids (TALLOC_CTX *mem_ctx,
mapi_id_t inbox_id, fid;
mapi_object_t obj_folder_inbox;
struct SPropTagArray *SPropTagArray;
- struct SPropValue *lpProps;
+ struct SPropValue *lpProps = NULL;
struct SRow aRow;
const struct BinaryArray_r *entryids;
struct Binary_r entryid;
@@ -5569,11 +5678,14 @@ mapi_get_ren_additional_fids (TALLOC_CTX *mem_ctx,
/* GetProps on Inbox for PR_ADDITIONAL_REN_ENTRYIDS */
SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_ADDITIONAL_REN_ENTRYIDS);
- lpProps = talloc_zero(mem_ctx, struct SPropValue);
ms = GetProps (&obj_folder_inbox, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, SPropTagArray, &lpProps, &count);
if (ms != MAPI_E_SUCCESS) {
make_mapi_error (perror, "GetProps", ms);
goto cleanup;
+ } else if (!lpProps) {
+ ms = MAPI_E_CALL_FAILED;
+ make_mapi_error (perror, "GetProps", ms);
+ goto cleanup;
}
if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
@@ -5608,6 +5720,7 @@ mapi_get_ren_additional_fids (TALLOC_CTX *mem_ctx,
cleanup:
mapi_object_release (&obj_folder_inbox);
+ talloc_free (lpProps);
return ms == MAPI_E_SUCCESS;
}
@@ -5679,8 +5792,8 @@ e_mapi_connection_get_folders_list (EMapiConnection *conn,
{
enum MAPISTATUS ms;
TALLOC_CTX *mem_ctx;
- struct SPropTagArray *SPropTagArray;
- struct SPropValue *lpProps;
+ struct SPropTagArray *SPropTagArray = NULL;
+ struct SPropValue *lpProps = NULL;
struct SRow aRow;
gboolean result = FALSE;
mapi_id_t mailbox_id;
@@ -5712,13 +5825,14 @@ e_mapi_connection_get_folders_list (EMapiConnection *conn,
goto cleanup;
}
- lpProps = talloc_zero(mem_ctx, struct SPropValue);
ms = GetProps (&priv->msg_store, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, SPropTagArray, &lpProps, &count);
- talloc_free (SPropTagArray);
-
if (ms != MAPI_E_SUCCESS) {
make_mapi_error (perror, "GetProps", ms);
goto cleanup;
+ } else if (!lpProps) {
+ ms = MAPI_E_CALL_FAILED;
+ make_mapi_error (perror, "GetProps", ms);
+ goto cleanup;
}
if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
@@ -5771,6 +5885,8 @@ e_mapi_connection_get_folders_list (EMapiConnection *conn,
g_slist_foreach (*mapi_folders, (GFunc) set_user_name, (gpointer) mailbox_user_name);
cleanup:
+ talloc_free (SPropTagArray);
+ talloc_free (lpProps);
talloc_free (mem_ctx);
UNLOCK ();
diff --git a/src/libexchangemapi/e-mapi-connection.h b/src/libexchangemapi/e-mapi-connection.h
index 6c03899..a32e2e7 100644
--- a/src/libexchangemapi/e-mapi-connection.h
+++ b/src/libexchangemapi/e-mapi-connection.h
@@ -229,6 +229,14 @@ gboolean e_mapi_connection_peek_store (EMapiConnection *conn,
GCancellable *cancellable,
GError **perror);
+gboolean e_mapi_connection_get_store_quotas (EMapiConnection *conn,
+ mapi_object_t *obj_store, /* can be NULL */
+ uint64_t *current_size, /* out */
+ uint64_t *receive_quota, /* out */
+ uint64_t *send_quota, /* out */
+ GCancellable *cancellable,
+ GError **perror);
+
gboolean e_mapi_connection_open_default_folder (EMapiConnection *conn,
uint32_t olFolderIdentifier,
mapi_object_t *obj_folder, /* out */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]