[evolution-kolab] CamelImapxAcl: API rework (update functions)



commit 9642ba21d0c4d69baa9a11e4ab8cd07769e351e7
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Fri Oct 5 18:09:11 2012 +0200

    CamelImapxAcl: API rework (update functions)
    
    * new function for updating a CamelImapxAcl from
      another CamelImapxAcl instance
    * new function for updating a CamelImapxAcl from
      a GList of CamelImapxAclEntry instances

 src/libekolab/camel-imapx-acl.c |  313 ++++++++++++++++++++++++++++++++++++---
 src/libekolab/camel-imapx-acl.h |   13 +-
 2 files changed, 300 insertions(+), 26 deletions(-)
---
diff --git a/src/libekolab/camel-imapx-acl.c b/src/libekolab/camel-imapx-acl.c
index 3f6e5c1..fabf15c 100644
--- a/src/libekolab/camel-imapx-acl.c
+++ b/src/libekolab/camel-imapx-acl.c
@@ -33,6 +33,8 @@
 #include <string.h>
 #include <glib/gi18n-lib.h>
 
+#include <libekolabutil/camel-system-headers.h>
+
 #include "camel-imapx-acl.h"
 
 /*----------------------------------------------------------------------------*/
@@ -54,7 +56,7 @@ static gboolean
 imapx_acl_entry_validate_rights (const gchar *rights,
                                  GError **err)
 {
-	g_return_val_if_fail (rights != NULL, FALSE);
+	/* rights may be NULL */
 	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
 
 	/* FIXME implement me */
@@ -75,6 +77,18 @@ imapx_acl_entry_gdestroy (gpointer data)
 	camel_imapx_acl_entry_free (entry);
 }
 
+static GHashTable*
+imapx_acl_entries_table_new (void)
+{
+	GHashTable *tbl = NULL;
+
+	tbl = g_hash_table_new_full (g_str_hash,
+	                             g_str_equal,
+	                             g_free,
+	                             g_free);
+	return tbl;
+}
+
 /*----------------------------------------------------------------------------*/
 
 CamelImapxAclSpec*
@@ -114,16 +128,18 @@ camel_imapx_acl_entry_new (const gchar *access_id,
 	GError *tmp_err = NULL;
 	gboolean ok = FALSE;
 
-	g_return_val_if_fail (access_id != NULL, NULL);
-	/* rights may be NULL */
+	/* access_id may be NULL (for MYRIGHTS) */
+	/* rights may be NULL (for no rights) */
 	g_return_val_if_fail (err == NULL || *err == NULL, NULL);
 
-	ok = imapx_acl_entry_validate_access_id (access_id,
-	                                         &tmp_err);
-	if (! ok)
-		goto exit;
+	if ((access_id != NULL) && (err != NULL)) {
+		ok = imapx_acl_entry_validate_access_id (access_id,
+		                                         &tmp_err);
+		if (! ok)
+			goto exit;
+	}
 
-	if (rights != NULL) {
+	if ((rights != NULL) && (err != NULL)) {
 		ok = imapx_acl_entry_validate_rights (rights,
 		                                      &tmp_err);
 		if (! ok)
@@ -268,18 +284,45 @@ GList*
 camel_imapx_acl_get_as_list (CamelImapxAcl *acl,
                              const gchar *mbox_name)
 {
+	CamelImapxAclEntry *entry = NULL;
+	GHashTable *entries_tbl = NULL;
+	GList *access_ids = NULL;
+	GList *access_ids_ptr = NULL;
+	GList *entries_lst = NULL;
+	gchar *rights = NULL;
+
 	g_return_val_if_fail (acl != NULL, NULL);
+	g_return_val_if_fail (acl->mboxes != NULL, NULL);
 	g_return_val_if_fail (mbox_name != NULL, NULL);
 
 	/* (acquire acl lock) */
 	g_mutex_lock (&(acl->lock));
 
-	g_warning ("%s()[%u] FIXME implement me", __func__, __LINE__);
+	entries_tbl = g_hash_table_lookup (acl->mboxes,
+	                                   mbox_name);
+	if (entries_tbl == NULL)
+		goto exit;
+
+	access_ids = g_hash_table_get_keys (entries_tbl);
+	access_ids_ptr = access_ids;
+	while (access_ids_ptr != NULL) {
+		rights = g_hash_table_lookup (entries_tbl,
+		                              access_ids_ptr->data);
+		entry = camel_imapx_acl_entry_new ((gchar *) access_ids_ptr->data,
+		                                   rights,
+		                                   NULL);
+		entries_lst = g_list_prepend (entries_lst, entry);
+		access_ids_ptr = g_list_next (access_ids_ptr);
+	}
+	g_list_free (access_ids);
 
+	if (entries_lst != NULL)
+		entries_lst = g_list_reverse (entries_lst);
+ exit:
 	/* (release acl lock) */
 	g_mutex_unlock (&(acl->lock));
 
-	return NULL;
+	return entries_lst;
 }
 
 GList*
@@ -320,10 +363,109 @@ camel_imapx_acl_free_list (GList *entries)
 }
 
 gboolean
-camel_imapx_acl_update_acl (CamelImapxAcl *acl,
-                            const gchar *mbox_name,
-                            const GList *entries,
-                            GError **err)
+camel_imapx_acl_update_from_acl (CamelImapxAcl *acl,
+                                 CamelImapxAcl *src_acl,
+                                 GError **err)
+{
+	GList *mbox_names = NULL;
+	GList *mbox_names_ptr = NULL;
+	GList *access_ids = NULL;
+	GList *access_ids_ptr = NULL;
+	GHashTable *src_entries = NULL;
+	GHashTable *new_entries = NULL;
+	gchar *rights = NULL;
+
+	g_return_val_if_fail (acl != NULL, FALSE);
+	g_return_val_if_fail (acl->mboxes != NULL, FALSE);
+	g_return_val_if_fail (acl->myrights != NULL, FALSE);
+	/* src_acl may be NULL */
+	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
+
+	if (src_acl == NULL)
+		return TRUE;
+
+	/* (acquire acl lock) */
+	g_mutex_lock (&(acl->lock));
+
+	/* (acquire src_acl lock) */
+	g_mutex_lock (&(src_acl->lock));
+
+	if (src_acl->mboxes == NULL)
+		goto acl_skip;
+
+	/* update general ACL */
+	mbox_names = g_hash_table_get_keys (src_acl->mboxes);
+	mbox_names_ptr = mbox_names;
+	while (mbox_names_ptr != NULL) {
+
+		src_entries = g_hash_table_lookup (src_acl->mboxes,
+		                                   mbox_names_ptr->data);
+		if (src_entries == NULL) {
+			/* should not happen */
+			g_warning ("%s()[%u] NULL ACL source entries table for '%s'",
+			           __func__, __LINE__, (gchar *) mbox_names_ptr->data);
+			(void) g_hash_table_remove (acl->mboxes,
+			                            mbox_names_ptr->data);
+			goto skip;
+		}
+
+		new_entries = imapx_acl_entries_table_new ();
+		access_ids = g_hash_table_get_keys (src_entries);
+		access_ids_ptr = access_ids;
+		while (access_ids_ptr != NULL) {
+			rights = g_hash_table_lookup (src_entries,
+			                              access_ids_ptr->data);
+			g_hash_table_insert (new_entries,
+			                     g_strdup ((gchar *) access_ids_ptr->data),
+			                     g_strdup (rights));
+
+			access_ids_ptr = g_list_next (access_ids_ptr);
+		}
+		g_list_free (access_ids);
+
+		g_hash_table_replace (acl->mboxes,
+		                      g_strdup ((gchar *) mbox_names_ptr->data),
+		                      new_entries);
+
+	skip:
+		mbox_names_ptr = g_list_next (mbox_names_ptr);
+	}
+	g_list_free (mbox_names);
+
+ acl_skip:
+
+	if (src_acl->myrights == NULL)
+		goto myrights_skip;
+
+	/* update MYRIGHTS */
+	mbox_names = g_hash_table_get_keys (src_acl->myrights);
+	mbox_names_ptr = mbox_names;
+	while (mbox_names_ptr) {
+		rights = g_hash_table_lookup (src_acl->myrights,
+		                              mbox_names_ptr->data);
+		g_hash_table_replace (acl->myrights,
+		                      g_strdup ((gchar *) mbox_names_ptr->data),
+		                      g_strdup (rights));
+		mbox_names_ptr = g_list_next (mbox_names_ptr);
+	}
+	g_list_free (mbox_names);
+
+ myrights_skip:
+
+	/* (release src_acl lock) */
+	g_mutex_unlock (&(src_acl->lock));
+
+	/* (release acl lock) */
+	g_mutex_unlock (&(acl->lock));
+
+	return TRUE;
+}
+
+gboolean
+camel_imapx_acl_update_from_list (CamelImapxAcl *acl,
+                                  const gchar *mbox_name,
+                                  const GList *entries,
+                                  GError **err)
 {
 	g_return_val_if_fail (acl != NULL, FALSE);
 	g_return_val_if_fail (mbox_name != NULL, FALSE);
@@ -348,18 +490,24 @@ gchar*
 camel_imapx_acl_get_myrights (CamelImapxAcl *acl,
                               const gchar *mbox_name)
 {
-	g_return_val_if_fail (acl != NULL, FALSE);
-	g_return_val_if_fail (mbox_name != NULL, FALSE);
+	gchar *r = NULL;
+	gchar *rights = NULL;
+
+	g_return_val_if_fail (acl != NULL, NULL);
+	g_return_val_if_fail (acl->myrights != NULL, NULL);
+	g_return_val_if_fail (mbox_name != NULL, NULL);
 
 	/* (acquire acl lock) */
 	g_mutex_lock (&(acl->lock));
 
-	g_warning ("%s()[%u] FIXME implement me", __func__, __LINE__);
+	r = g_hash_table_lookup (acl->myrights,
+	                         mbox_name);
+	rights = g_strdup (r);
 
 	/* (release acl lock) */
 	g_mutex_unlock (&(acl->lock));
 
-	return NULL;
+	return rights;
 }
 
 gboolean
@@ -390,7 +538,17 @@ camel_imapx_acl_update_acl_from_server_response (CamelImapxAcl *acl,
                                                  GCancellable *cancellable,
                                                  GError **err)
 {
+	gint tok = 0;
+	guchar *token = NULL;
+	gchar *mbox_name = NULL;
+	gchar *access_id = NULL;
+	gchar *rights = NULL;
+	GHashTable *entries_tbl = NULL;
+	GError *tmp_err = NULL;
+	gboolean ok = FALSE;
+
 	g_return_val_if_fail (acl != NULL, FALSE);
+	g_return_val_if_fail (acl->mboxes != NULL, FALSE);
 	g_return_val_if_fail (CAMEL_IS_IMAPX_STREAM (is), FALSE);
 	/* cancellable may be NULL */
 	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
@@ -398,12 +556,83 @@ camel_imapx_acl_update_acl_from_server_response (CamelImapxAcl *acl,
 	/* (acquire acl lock) */
 	g_mutex_lock (&(acl->lock));
 
-	g_warning ("%s()[%u] FIXME implement me", __func__, __LINE__);
+	/* mailbox name */
+	tok = camel_imapx_stream_astring (is, &token, cancellable, &tmp_err);
+	if (tmp_err != NULL) {
+		g_warning ("%s()[%u] stream error, token %u: %s",
+		           __func__, __LINE__, tok, tmp_err->message);
+		goto exit;
+	}
+	mbox_name = g_strdup ((gchar *) token);
+
+	/* Where to dump the ACL entries into.
+	 * If we have a cached ACL table for a folder, we
+	 * need to drop it even if reading from the server
+	 * fails (better not to show any data than to show
+	 * incorrect or obsoleted data)
+	 */
+	entries_tbl = imapx_acl_entries_table_new ();
+	g_hash_table_replace (acl->mboxes,
+	                      g_strdup (mbox_name),
+	                      entries_tbl);
+
+#if 0 /* FIXME how to tell if we're done reading? CamelIMAPXStream is always at EOS, it seems... */
+	if (camel_stream_eos (CAMEL_STREAM (is))) {
+		g_hash_table_remove_all (entries_tbl);
+		goto skip;
+	}
+#endif
+	/* access_id,rights pairs */
+	while (TRUE) {
+		tok = camel_imapx_stream_astring (is, &token, cancellable, &tmp_err);
+		if (tmp_err != NULL) {
+			g_warning ("%s()[%u] stream error, token %u: %s",
+			           __func__, __LINE__, tok, tmp_err->message);
+			goto exit;
+		}
+		access_id = g_strdup ((gchar *) token);
+		tok = camel_imapx_stream_astring (is, &token, cancellable, &tmp_err);
+		if (tmp_err != NULL) {
+			g_warning ("%s()[%u] stream error, token %u: %s",
+			           __func__, __LINE__, tok, tmp_err->message);
+			goto exit;
+		}
+		rights = g_strdup ((gchar *) token);
+
+		if (! imapx_acl_entry_validate_access_id (access_id, &tmp_err))
+			goto exit;
+		if (! imapx_acl_entry_validate_rights (rights, &tmp_err))
+			goto exit;
+
+		g_hash_table_replace (entries_tbl, access_id, rights);
+		access_id = NULL;
+		rights = NULL;
+
+		/* FIXME CamelIMAPXStream is always EOS??!? */
+		if (camel_stream_eos (CAMEL_STREAM (is)))
+			break;
+	}
+#if 0
+ skip:
+#endif
+	ok = TRUE;
+
+ exit:
+	if (tmp_err != NULL) {
+		g_propagate_error (err, tmp_err);
+		if (access_id != NULL)
+			g_free (access_id);
+		if (rights != NULL)
+			g_free (rights);
+	}
+
+	if (mbox_name != NULL)
+		g_free (mbox_name);
 
 	/* (release acl lock) */
 	g_mutex_unlock (&(acl->lock));
 
-	return TRUE;
+	return ok;
 }
 
 gboolean
@@ -412,7 +641,15 @@ camel_imapx_acl_update_myrights_from_server_response (CamelImapxAcl *acl,
                                                       GCancellable *cancellable,
                                                       GError **err)
 {
+	gint tok = 0;
+	guchar *token = NULL;
+	gchar *mbox_name = NULL;
+	gchar *rights = NULL;
+	GError *tmp_err = NULL;
+	gboolean ok = FALSE;
+
 	g_return_val_if_fail (acl != NULL, FALSE);
+	g_return_val_if_fail (acl->myrights != NULL, FALSE);
 	g_return_val_if_fail (CAMEL_IS_IMAPX_STREAM (is), FALSE);
 	/* cancellable may be NULL */
 	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
@@ -420,12 +657,44 @@ camel_imapx_acl_update_myrights_from_server_response (CamelImapxAcl *acl,
 	/* (acquire acl lock) */
 	g_mutex_lock (&(acl->lock));
 
-	g_warning ("%s()[%u] FIXME implement me", __func__, __LINE__);
+	/* read mailbox name */
+	tok = camel_imapx_stream_astring (is, &token, cancellable, &tmp_err);
+	if (tmp_err != NULL) {
+		g_warning ("%s()[%u] stream error, token %u: %s",
+		           __func__, __LINE__, tok, tmp_err->message);
+		goto exit;
+	}
+	mbox_name = g_strdup ((gchar *) token);
+
+	/* read MYRIGHTS string */
+	tok = camel_imapx_stream_astring (is, &token, cancellable, &tmp_err);
+	if (tmp_err != NULL) {
+		g_warning ("%s()[%u] stream error, token %u: %s",
+		           __func__, __LINE__, tok, tmp_err->message);
+		goto exit;
+	}
+	rights = g_strdup ((gchar *) token);
+
+	/* rights string validation */
+	if (! imapx_acl_entry_validate_rights (rights, &tmp_err))
+		goto exit;
+
+	g_hash_table_replace (acl->myrights, mbox_name, rights);
+	ok = TRUE;
+
+ exit:
+	if (tmp_err != NULL) {
+		g_propagate_error (err, tmp_err);
+		if (rights != NULL)
+			g_free (rights);
+		if (mbox_name != NULL)
+			g_free (mbox_name);
+	}
 
 	/* (release acl lock) */
 	g_mutex_unlock (&(acl->lock));
 
-	return TRUE;
+	return ok;
 }
 
 GSList*
diff --git a/src/libekolab/camel-imapx-acl.h b/src/libekolab/camel-imapx-acl.h
index 56d89db..11a170a 100644
--- a/src/libekolab/camel-imapx-acl.h
+++ b/src/libekolab/camel-imapx-acl.h
@@ -111,10 +111,15 @@ void
 camel_imapx_acl_free_list (GList *entries);
 
 gboolean
-camel_imapx_acl_update_acl (CamelImapxAcl *acl,
-                            const gchar *mbox_name,
-                            const GList *entries,
-                            GError **err);
+camel_imapx_acl_update_from_acl (CamelImapxAcl *acl,
+                                 CamelImapxAcl *src_acl,
+                                 GError **err);
+
+gboolean
+camel_imapx_acl_update_from_list (CamelImapxAcl *acl,
+                                  const gchar *mbox_name,
+                                  const GList *entries,
+                                  GError **err);
 
 gchar*
 camel_imapx_acl_get_myrights (CamelImapxAcl *acl,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]