evolution-data-server r8728 - in branches/camel-db-summary: . camel camel/providers/imap libedataserver libedataserverui po
- From: sragavan svn gnome org
- To: svn-commits-list gnome org
- Subject: evolution-data-server r8728 - in branches/camel-db-summary: . camel camel/providers/imap libedataserver libedataserverui po
- Date: Mon, 5 May 2008 04:19:52 +0100 (BST)
Author: sragavan
Date: Mon May 5 03:19:52 2008
New Revision: 8728
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=8728&view=rev
Log:
Merge branch 'master' into new_summary
Modified:
branches/camel-db-summary/ChangeLog
branches/camel-db-summary/camel/ChangeLog
branches/camel-db-summary/camel/camel-folder-summary.c
branches/camel-db-summary/camel/camel-session.c
branches/camel-db-summary/camel/camel-session.h
branches/camel-db-summary/camel/providers/imap/ChangeLog
branches/camel-db-summary/camel/providers/imap/camel-imap-folder.c
branches/camel-db-summary/configure.in
branches/camel-db-summary/libedataserver/e-categories.c
branches/camel-db-summary/libedataserver/e-categories.h
branches/camel-db-summary/libedataserverui/ChangeLog
branches/camel-db-summary/libedataserverui/e-passwords.c
branches/camel-db-summary/po/ChangeLog
branches/camel-db-summary/po/he.po
Modified: branches/camel-db-summary/camel/camel-folder-summary.c
==============================================================================
--- branches/camel-db-summary/camel/camel-folder-summary.c (original)
+++ branches/camel-db-summary/camel/camel-folder-summary.c Mon May 5 03:19:52 2008
@@ -527,7 +527,7 @@
if (ci == NULL)
return NULL;
- if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500) {
+ if (camel_file_util_decode_uint32(in, &count) == -1) {
camel_folder_summary_content_info_free (s, ci);
return NULL;
}
@@ -1872,7 +1872,7 @@
camel_file_util_decode_fixed_int32(in, &mi->message_id.id.part.hi);
camel_file_util_decode_fixed_int32(in, &mi->message_id.id.part.lo);
- if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
+ if (camel_file_util_decode_uint32(in, &count) == -1)
goto error;
if (count > 0) {
@@ -1884,7 +1884,7 @@
}
}
- if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
+ if (camel_file_util_decode_uint32(in, &count) == -1)
goto error;
for (i=0;i<count;i++) {
@@ -1895,7 +1895,7 @@
g_free(name);
}
- if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
+ if (camel_file_util_decode_uint32(in, &count) == -1)
goto error;
for (i=0;i<count;i++) {
@@ -2049,7 +2049,8 @@
ct = camel_content_type_new(type, subtype);
g_free(type); /* can this be removed? */
g_free(subtype);
- if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
+
+ if (camel_file_util_decode_uint32(in, &count) == -1)
goto error;
for (i = 0; i < count; i++) {
Modified: branches/camel-db-summary/camel/camel-session.c
==============================================================================
--- branches/camel-db-summary/camel/camel-session.c (original)
+++ branches/camel-db-summary/camel/camel-session.c Mon May 5 03:19:52 2008
@@ -536,12 +536,13 @@
CS_CLASS(m->session)->thread_status(m->session, m, what, pc);
}
-static void *session_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size)
+static void *
+session_thread_msg_new (CamelSession *session,
+ CamelSessionThreadOps *ops,
+ unsigned int size)
{
CamelSessionThreadMsg *m;
- g_assert(size >= sizeof(*m));
-
m = g_malloc0(size);
m->ops = ops;
m->session = session;
@@ -556,9 +557,12 @@
return m;
}
-static void session_thread_msg_free(CamelSession *session, CamelSessionThreadMsg *msg)
+static void
+session_thread_msg_free (CamelSession *session,
+ CamelSessionThreadMsg *msg)
{
- g_assert(msg->ops != NULL);
+ g_return_if_fail (CAMEL_IS_SESSION (session));
+ g_return_if_fail (msg != NULL && msg->ops != NULL);
d(printf("free message %p session %p\n", msg, session));
@@ -578,7 +582,8 @@
}
static void
-session_thread_proxy(CamelSessionThreadMsg *msg, CamelSession *session)
+session_thread_proxy (CamelSessionThreadMsg *msg,
+ CamelSession *session)
{
if (msg->ops->receive) {
CamelOperation *oldop;
@@ -591,7 +596,10 @@
camel_session_thread_msg_free(session, msg);
}
-static int session_thread_queue(CamelSession *session, CamelSessionThreadMsg *msg, int flags)
+static int
+session_thread_queue (CamelSession *session,
+ CamelSessionThreadMsg *msg,
+ int flags)
{
GThreadPool *thread_pool;
int id;
@@ -612,7 +620,9 @@
return id;
}
-static void session_thread_wait(CamelSession *session, int id)
+static void
+session_thread_wait (CamelSession *session,
+ int id)
{
int wait;
@@ -627,7 +637,11 @@
} while (wait);
}
-static void session_thread_status(CamelSession *session, CamelSessionThreadMsg *msg, const char *text, int pc)
+static void
+session_thread_status (CamelSession *session,
+ CamelSessionThreadMsg *msg,
+ const char *text,
+ int pc)
{
}
@@ -646,13 +660,15 @@
* Returns a new #CamelSessionThreadMsg
**/
void *
-camel_session_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size)
-{
- g_assert(CAMEL_IS_SESSION(session));
- g_assert(ops != NULL);
- g_assert(size >= sizeof(CamelSessionThreadMsg));
+camel_session_thread_msg_new (CamelSession *session,
+ CamelSessionThreadOps *ops,
+ unsigned int size)
+{
+ g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL);
+ g_return_val_if_fail (ops != NULL, NULL);
+ g_return_val_if_fail (size >= sizeof (CamelSessionThreadMsg), NULL);
- return CS_CLASS (session)->thread_msg_new(session, ops, size);
+ return CS_CLASS (session)->thread_msg_new (session, ops, size);
}
/**
@@ -664,13 +680,13 @@
* msg_new, and must nto have been submitted to any queue function.
**/
void
-camel_session_thread_msg_free(CamelSession *session, CamelSessionThreadMsg *msg)
+camel_session_thread_msg_free (CamelSession *session,
+ CamelSessionThreadMsg *msg)
{
- g_assert(CAMEL_IS_SESSION(session));
- g_assert(msg != NULL);
- g_assert(msg->ops != NULL);
+ g_return_if_fail (CAMEL_IS_SESSION (session));
+ g_return_if_fail (msg != NULL && msg->ops != NULL);
- CS_CLASS (session)->thread_msg_free(session, msg);
+ CS_CLASS (session)->thread_msg_free (session, msg);
}
/**
@@ -686,12 +702,14 @@
* Returns the id of the operation queued
**/
int
-camel_session_thread_queue(CamelSession *session, CamelSessionThreadMsg *msg, int flags)
+camel_session_thread_queue (CamelSession *session,
+ CamelSessionThreadMsg *msg,
+ int flags)
{
- g_assert(CAMEL_IS_SESSION(session));
- g_assert(msg != NULL);
+ g_return_val_if_fail (CAMEL_IS_SESSION (session), -1);
+ g_return_val_if_fail (msg != NULL, -1);
- return CS_CLASS (session)->thread_queue(session, msg, flags);
+ return CS_CLASS (session)->thread_queue (session, msg, flags);
}
/**
@@ -702,14 +720,15 @@
* Wait on an operation to complete (by id).
**/
void
-camel_session_thread_wait(CamelSession *session, int id)
+camel_session_thread_wait (CamelSession *session,
+ int id)
{
- g_assert(CAMEL_IS_SESSION(session));
+ g_return_if_fail (CAMEL_IS_SESSION (session));
if (id == -1)
return;
- CS_CLASS (session)->thread_wait(session, id);
+ CS_CLASS (session)->thread_wait (session, id);
}
/**
@@ -723,7 +742,7 @@
gboolean
camel_session_check_junk (CamelSession *session)
{
- g_assert(CAMEL_IS_SESSION(session));
+ g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE);
return session->check_junk;
}
@@ -736,9 +755,10 @@
* Set check_junk flag, if set, incoming mail will be checked for being junk.
**/
void
-camel_session_set_check_junk (CamelSession *session, gboolean check_junk)
+camel_session_set_check_junk (CamelSession *session,
+ gboolean check_junk)
{
- g_assert(CAMEL_IS_SESSION(session));
+ g_return_if_fail (CAMEL_IS_SESSION (session));
session->check_junk = check_junk;
}
@@ -746,24 +766,30 @@
gboolean
camel_session_get_network_state (CamelSession *session)
{
- g_return_val_if_fail (CAMEL_IS_SESSION(session), FALSE);
+ g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE);
return session->network_state;
}
void
-camel_session_set_network_state (CamelSession *session, gboolean network_state)
+camel_session_set_network_state (CamelSession *session,
+ gboolean network_state)
{
- g_return_if_fail (CAMEL_IS_SESSION(session));
+ g_return_if_fail (CAMEL_IS_SESSION (session));
session->network_state = network_state;
}
void
-camel_session_set_junk_headers (CamelSession *session, const char **headers, const char **values, int len)
+camel_session_set_junk_headers (CamelSession *session,
+ const char **headers,
+ const char **values,
+ int len)
{
int i;
+ g_return_if_fail (CAMEL_IS_SESSION (session));
+
if (session->priv->junk_headers) {
g_hash_table_remove_all (session->priv->junk_headers);
g_hash_table_destroy (session->priv->junk_headers);
@@ -779,5 +805,7 @@
const GHashTable *
camel_session_get_junk_headers (CamelSession *session)
{
+ g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL);
+
return session->priv->junk_headers;
}
Modified: branches/camel-db-summary/camel/camel-session.h
==============================================================================
--- branches/camel-db-summary/camel/camel-session.h (original)
+++ branches/camel-db-summary/camel/camel-session.h Mon May 5 03:19:52 2008
@@ -103,12 +103,22 @@
CamelException *ex);
/* mechanism for creating and maintaining multiple threads of control */
- void *(*thread_msg_new)(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size);
- void (*thread_msg_free)(CamelSession *session, CamelSessionThreadMsg *msg);
- int (*thread_queue)(CamelSession *session, CamelSessionThreadMsg *msg, int flags);
- void (*thread_wait)(CamelSession *session, int id);
- void (*thread_status)(CamelSession *session, CamelSessionThreadMsg *msg, const char *text, int pc);
- gboolean (*lookup_addressbook) (CamelSession *session, const char *name);
+ void * (*thread_msg_new) (CamelSession *session,
+ CamelSessionThreadOps *ops,
+ unsigned int size);
+ void (*thread_msg_free) (CamelSession *session,
+ CamelSessionThreadMsg *msg);
+ int (*thread_queue) (CamelSession *session,
+ CamelSessionThreadMsg *msg,
+ int flags);
+ void (*thread_wait) (CamelSession *session,
+ int id);
+ void (*thread_status) (CamelSession *session,
+ CamelSessionThreadMsg *msg,
+ const char *text,
+ int pc);
+ gboolean (*lookup_addressbook)(CamelSession *session,
+ const char *name);
} CamelSessionClass;
@@ -131,9 +141,11 @@
CamelException *ex);
#define camel_session_get_store(session, url_string, ex) \
- ((CamelStore *) camel_session_get_service_connected (session, url_string, CAMEL_PROVIDER_STORE, ex))
+ ((CamelStore *) camel_session_get_service_connected \
+ (session, url_string, CAMEL_PROVIDER_STORE, ex))
#define camel_session_get_transport(session, url_string, ex) \
- ((CamelTransport *) camel_session_get_service_connected (session, url_string, CAMEL_PROVIDER_TRANSPORT, ex))
+ ((CamelTransport *) camel_session_get_service_connected \
+ (session, url_string, CAMEL_PROVIDER_TRANSPORT, ex))
char * camel_session_get_storage_path (CamelSession *session,
CamelService *service,
@@ -156,7 +168,7 @@
const char *prompt,
gboolean cancel);
-char * camel_session_build_password_prompt
+char * camel_session_build_password_prompt
(const char *type,
const char *user,
const char *host);
@@ -169,9 +181,9 @@
const char *type,
CamelException *ex);
-gboolean camel_session_check_junk (CamelSession *session);
-void camel_session_set_check_junk (CamelSession *session,
- gboolean check_junk);
+gboolean camel_session_check_junk (CamelSession *session);
+void camel_session_set_check_junk (CamelSession *session,
+ gboolean check_junk);
struct _CamelSessionThreadOps {
void (*receive)(CamelSession *session, struct _CamelSessionThreadMsg *m);
@@ -192,15 +204,26 @@
/* user fields follow */
};
-void *camel_session_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size);
-void camel_session_thread_msg_free(CamelSession *session, CamelSessionThreadMsg *msg);
-int camel_session_thread_queue(CamelSession *session, CamelSessionThreadMsg *msg, int flags);
-void camel_session_thread_wait(CamelSession *session, int id);
-gboolean camel_session_get_network_state (CamelSession *session);
-void camel_session_set_network_state (CamelSession *session, gboolean network_state);
-const GHashTable * camel_session_get_junk_headers (CamelSession *session);
-void camel_session_set_junk_headers (CamelSession *session, const char **headers, const char **values, int len);
-gboolean camel_session_lookup_addressbook (CamelSession *session, const char *name);
+void * camel_session_thread_msg_new (CamelSession *session,
+ CamelSessionThreadOps *ops,
+ unsigned int size);
+void camel_session_thread_msg_free (CamelSession *session,
+ CamelSessionThreadMsg *msg);
+int camel_session_thread_queue (CamelSession *session,
+ CamelSessionThreadMsg *msg,
+ int flags);
+void camel_session_thread_wait (CamelSession *session,
+ int id);
+gboolean camel_session_get_network_state (CamelSession *session);
+void camel_session_set_network_state (CamelSession *session,
+ gboolean network_state);
+const GHashTable * camel_session_get_junk_headers (CamelSession *session);
+void camel_session_set_junk_headers (CamelSession *session,
+ const char **headers,
+ const char **values,
+ int len);
+gboolean camel_session_lookup_addressbook (CamelSession *session,
+ const char *name);
G_END_DECLS
Modified: branches/camel-db-summary/camel/providers/imap/camel-imap-folder.c
==============================================================================
--- branches/camel-db-summary/camel/providers/imap/camel-imap-folder.c (original)
+++ branches/camel-db-summary/camel/providers/imap/camel-imap-folder.c Mon May 5 03:19:52 2008
@@ -1847,6 +1847,10 @@
if (!destset++)
goto lose;
+ /* first do NOOP on the destination folder, so server has enough time to propagate our copy command there */
+ camel_imap_response_free (CAMEL_IMAP_STORE (destination->parent_store),
+ camel_imap_command (CAMEL_IMAP_STORE (destination->parent_store), destination, NULL, "NOOP"));
+
camel_exception_init (&ex);
/* refresh folder's summary first, we copied messages there on the server,
but do not know about it in a local summary */
@@ -1898,6 +1902,39 @@
g_warning ("Bad COPYUID response from server");
}
+/* returns whether any of messages from uidset has set any user tag or not */
+static gboolean
+any_has_user_tag (CamelFolder *source, char *uidset)
+{
+ GPtrArray *src;
+
+ g_return_val_if_fail (source != NULL && uidset != NULL, FALSE);
+
+ src = imap_uid_set_to_array (source->summary, uidset);
+ if (src) {
+ gboolean have = FALSE;
+ int i;
+
+ CAMEL_IMAP_FOLDER_REC_LOCK (source, cache_lock);
+ for (i = 0; i < src->len && !have; i++) {
+ CamelMessageInfo *mi = camel_folder_get_message_info (source, src->pdata[i]);
+
+ if (mi) {
+ have = camel_message_info_user_tags (mi) != NULL;
+
+ camel_folder_free_message_info (source, mi);
+ }
+ }
+ CAMEL_IMAP_FOLDER_REC_UNLOCK (source, cache_lock);
+
+ imap_uid_array_free (src);
+
+ return have;
+ }
+
+ return FALSE;
+}
+
static void
do_copy (CamelFolder *source, GPtrArray *uids,
CamelFolder *destination, int delete_originals, CamelException *ex)
@@ -1910,9 +1947,10 @@
while (uid < uids->len && !camel_exception_is_set (ex)) {
uidset = imap_uid_array_to_set (source->summary, uids, uid, UID_SET_LIMIT, &uid);
- if ((store->capabilities & IMAP_CAPABILITY_XGWMOVE) && delete_originals) {
+ /* use XGWMOVE only when none of the moving messages has set any user tag */
+ if ((store->capabilities & IMAP_CAPABILITY_XGWMOVE) != 0 && delete_originals && !any_has_user_tag (source, uidset)) {
response = camel_imap_command (store, source, ex, "UID XGWMOVE %s %F", uidset, destination->full_name);
- /* TODO: EXPUNGE returns??? */
+ /* returns only 'A00012 OK UID XGWMOVE completed' '* 2 XGWMOVE' so nothing useful */
camel_imap_response_free (store, response);
} else {
response = camel_imap_command (store, source, ex, "UID COPY %s %F", uidset, destination->full_name);
Modified: branches/camel-db-summary/configure.in
==============================================================================
--- branches/camel-db-summary/configure.in (original)
+++ branches/camel-db-summary/configure.in Mon May 5 03:19:52 2008
@@ -22,6 +22,7 @@
m4_define([libgnome_minimum_version], [2.0.0]) # XXX Just a Guess
m4_define([libxml_minimum_version], [2.0.0]) # XXX Just a Guess
m4_define([libsoup_minimum_version], [2.3.0])
+m4_define([gnome_keyring_minimum_version], [2.20.1])
dnl *************************************************************************************************
dnl Base Version
@@ -453,7 +454,7 @@
with_nss_libs="$withval")
if test "x${enable_gnome_keyring}" = "xyes"; then
- PKG_CHECK_MODULES(GNOME_KEYRING, gnome-keyring-1, with_gnome_keyring="yes", with_gnome_keyring="no");
+ PKG_CHECK_MODULES(GNOME_KEYRING, gnome-keyring-1 >= gnome_keyring_minimum_version, with_gnome_keyring="yes", with_gnome_keyring="no");
if test "x$with_gnome_keyring" = "xyes"; then
AC_DEFINE(WITH_GNOME_KEYRING, 1, [Gnome Keyring available])
GNOME_KEYRING_REQUIREMENT="gnome-keyring-1"
Modified: branches/camel-db-summary/libedataserver/e-categories.c
==============================================================================
--- branches/camel-db-summary/libedataserver/e-categories.c (original)
+++ branches/camel-db-summary/libedataserver/e-categories.c Mon May 5 03:19:52 2008
@@ -66,10 +66,55 @@
{ NULL }
};
+/* ------------------------------------------------------------------------- */
+
+typedef struct {
+ GObject object;
+} EChangedListener;
+
+typedef struct {
+ GObjectClass parent_class;
+
+ void (* changed) (void);
+} EChangedListenerClass;
+
+static GType e_changed_listener_get_type (void);
+
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+static guint changed_listener_signals[LAST_SIGNAL];
+
+static void
+e_changed_listener_class_init (EChangedListenerClass *klass)
+{
+ changed_listener_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EChangedListenerClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+e_changed_listener_init (EChangedListener *changed)
+{
+}
+
+G_DEFINE_TYPE (EChangedListener, e_changed_listener, G_TYPE_OBJECT);
+
+/* ------------------------------------------------------------------------- */
+
static gboolean initialized = FALSE;
static GHashTable *categories_table = NULL;
static gboolean save_is_pending = FALSE;
static guint idle_id = 0;
+static EChangedListener *listeners = NULL;
+static gboolean changed = FALSE;
static gchar *
build_categories_filename (void)
@@ -179,6 +224,10 @@
g_free (filename);
save_is_pending = FALSE;
+ if (changed)
+ g_signal_emit_by_name (listeners, "changed");
+
+ changed = FALSE;
exit:
idle_id = 0;
return FALSE;
@@ -380,6 +429,11 @@
categories_table = NULL;
}
+ if (listeners != NULL) {
+ g_object_unref (listeners);
+ listeners = NULL;
+ }
+
initialized = FALSE;
}
@@ -397,6 +451,8 @@
g_str_hash, g_str_equal, g_free,
(GDestroyNotify) free_category_info);
+ listeners = g_object_new (e_changed_listener_get_type (), NULL);
+
g_atexit (finalize_categories);
n_added = load_categories ();
@@ -479,6 +535,7 @@
g_hash_table_insert (categories_table, g_strdup (category), cat_info);
+ changed = TRUE;
save_categories ();
}
@@ -496,8 +553,10 @@
if (!initialized)
initialize_categories ();
- if (g_hash_table_remove (categories_table, category))
+ if (g_hash_table_remove (categories_table, category)) {
+ changed = TRUE;
save_categories ();
+ }
}
/**
@@ -571,6 +630,7 @@
g_free (cat_info->color);
cat_info->color = g_strdup (color);
+ changed = TRUE;
save_categories ();
}
#endif /* EDS_DISABLE_DEPRECATED */
@@ -622,6 +682,7 @@
g_free (cat_info->icon_file);
cat_info->icon_file = g_strdup (icon_file);
+ changed = TRUE;
save_categories ();
}
@@ -649,3 +710,36 @@
return cat_info->searchable;
}
+
+/**
+ * e_categories_register_change_listener:
+ * @listener: the callback to be called on any category change.
+ * @user_data: used data passed to the @listener when called.
+ *
+ * Registers callback to be called on change of any category.
+ * Pair listener and user_data is used to distinguish between listeners.
+ * Listeners can be unregistered with @e_categories_unregister_change_listener.
+ **/
+void
+e_categories_register_change_listener (GCallback listener, gpointer user_data)
+{
+ if (!initialized)
+ initialize_categories ();
+
+ g_signal_connect (listeners, "changed", listener, user_data);
+}
+
+/**
+ * e_categories_unregister_change_listener:
+ * @listener: Callback to be removed.
+ * @user_data: User data as passed with call to @e_categories_register_change_listener.
+ *
+ * Removes previously registered callback from the list of listeners on changes.
+ * If it was not registered, then does nothing.
+ **/
+void
+e_categories_unregister_change_listener (GCallback listener, gpointer user_data)
+{
+ if (initialized)
+ g_signal_handlers_disconnect_by_func (listeners, listener, user_data);
+}
Modified: branches/camel-db-summary/libedataserver/e-categories.h
==============================================================================
--- branches/camel-db-summary/libedataserver/e-categories.h (original)
+++ branches/camel-db-summary/libedataserver/e-categories.h Mon May 5 03:19:52 2008
@@ -20,6 +20,7 @@
#ifndef __E_CATEGORIES__
#define __E_CATEGORIES__
+#include <glib-object.h>
#include <glib/glist.h>
#include <glib/gmacros.h>
@@ -41,6 +42,9 @@
void e_categories_set_icon_file_for (const char *category, const char *icon_file);
gboolean e_categories_is_searchable (const char *category);
+void e_categories_register_change_listener (GCallback listener, gpointer user_data);
+void e_categories_unregister_change_listener (GCallback listener, gpointer user_data);
+
G_END_DECLS
#endif
Modified: branches/camel-db-summary/libedataserverui/e-passwords.c
==============================================================================
--- branches/camel-db-summary/libedataserverui/e-passwords.c (original)
+++ branches/camel-db-summary/libedataserverui/e-passwords.c Mon May 5 03:19:52 2008
@@ -73,6 +73,7 @@
/* output */
gboolean *remember;
gchar *password;
+ GError *error;
/* work variables */
GtkWidget *entry;
@@ -176,6 +177,21 @@
}
#ifdef WITH_GNOME_KEYRING
+
+/* XXX Unfortunately, gnome-keyring doesn't use GErrors. */
+#define EP_KEYRING_ERROR (ep_keyring_error_domain ())
+
+static GQuark
+ep_keyring_error_domain (void)
+{
+ static GQuark quark = 0;
+
+ if (G_UNLIKELY (quark == 0))
+ quark = g_quark_from_static_string ("ep-keyring-error-quark");
+
+ return quark;
+}
+
static EUri *
ep_keyring_uri_new (const gchar *string)
{
@@ -243,7 +259,8 @@
static gboolean
ep_keyring_delete_passwords (const gchar *user,
const gchar *server,
- GList *passwords)
+ GList *passwords,
+ GError **error)
{
while (passwords != NULL) {
GnomeKeyringFound *found = passwords->data;
@@ -257,7 +274,8 @@
result = gnome_keyring_item_delete_sync (NULL, found->item_id);
if (result != GNOME_KEYRING_RESULT_OK) {
- g_warning (
+ g_set_error (
+ error, EP_KEYRING_ERROR, result,
"Unable to delete password in "
"keyring (Keyring reports: %s)",
gnome_keyring_result_to_message (result));
@@ -274,7 +292,8 @@
ep_keyring_insert_password (const gchar *user,
const gchar *server,
const gchar *display_name,
- const gchar *password)
+ const gchar *password,
+ GError **error)
{
GnomeKeyringAttributeList *attributes;
GnomeKeyringResult result;
@@ -299,7 +318,8 @@
NULL, GNOME_KEYRING_ITEM_NETWORK_PASSWORD,
display_name, attributes, password, TRUE, &item_id);
if (result != GNOME_KEYRING_RESULT_OK) {
- g_warning (
+ g_set_error (
+ error, EP_KEYRING_ERROR, result,
"Unable to create password in "
"keyring (Keyring reports: %s)",
gnome_keyring_result_to_message (result));
@@ -312,7 +332,8 @@
static GList *
ep_keyring_lookup_passwords (const gchar *user,
- const gchar *server)
+ const gchar *server,
+ GError **error)
{
GnomeKeyringAttributeList *attributes;
GnomeKeyringResult result;
@@ -331,7 +352,8 @@
result = gnome_keyring_find_items_sync (
GNOME_KEYRING_ITEM_NETWORK_PASSWORD, attributes, &passwords);
if (result != GNOME_KEYRING_RESULT_OK) {
- g_warning (
+ g_set_error (
+ error, EP_KEYRING_ERROR, result,
"Unable to find password(s) in "
"keyring (Keyring reports: %s)",
gnome_keyring_result_to_message (result));
@@ -412,6 +434,13 @@
static void
ep_msg_free (EPassMsg *msg)
{
+ /* XXX We really should be passing this back to the caller, but
+ * doing so will require breaking the password API. */
+ if (msg->error != NULL) {
+ g_warning ("%s", msg->error->message);
+ g_error_free (msg->error);
+ }
+
e_flag_free (msg->done);
g_free (msg->password);
g_free (msg);
@@ -447,13 +476,23 @@
ep_clear_passwords_keyring (EPassMsg *msg)
{
GList *passwords;
+ GError *error = NULL;
/* Find all Evolution passwords and delete them. */
- passwords = ep_keyring_lookup_passwords (NULL, NULL);
+ passwords = ep_keyring_lookup_passwords (NULL, NULL, &error);
if (passwords != NULL) {
- ep_keyring_delete_passwords (NULL, NULL, passwords);
+ ep_keyring_delete_passwords (NULL, NULL, passwords, &error);
gnome_keyring_found_list_free (passwords);
}
+
+ /* Not finding the requested key is acceptable, but we still
+ * want to leave an informational message on the terminal. */
+ if (g_error_matches (error, EP_KEYRING_ERROR, GNOME_KEYRING_RESULT_NO_MATCH)) {
+ g_message ("%s", error->message);
+ g_error_free (error);
+
+ } else if (error != NULL)
+ g_propagate_error (&msg->error, error);
}
#endif
@@ -474,11 +513,8 @@
g_message ("%s", error->message);
g_error_free (error);
- /* Issue a warning if anything else goes wrong. */
- } else if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
+ } else if (error != NULL)
+ g_propagate_error (&msg->error, error);
g_free (group);
}
@@ -504,13 +540,18 @@
ep_forget_passwords_keyring (EPassMsg *msg)
{
GList *passwords;
+ GError *error = NULL;
/* Find all Evolution passwords and delete them. */
- passwords = ep_keyring_lookup_passwords (NULL, NULL);
+ passwords = ep_keyring_lookup_passwords (NULL, NULL, &error);
if (passwords != NULL) {
- ep_keyring_delete_passwords (NULL, NULL, passwords);
+ ep_keyring_delete_passwords (NULL, NULL, passwords, &error);
gnome_keyring_found_list_free (passwords);
+
}
+
+ if (error != NULL)
+ g_propagate_error (&msg->error, error);
}
#endif
@@ -569,6 +610,7 @@
{
gchar *password;
EUri *uri;
+ GError *error = NULL;
password = g_hash_table_lookup (password_cache, msg->key);
if (password == NULL) {
@@ -581,9 +623,12 @@
/* Only remove the password from the session hash
* if the keyring insertion was successful. */
- if (ep_keyring_insert_password (uri->user, uri->host, msg->key, password))
+ if (ep_keyring_insert_password (uri->user, uri->host, msg->key, password, &error))
g_hash_table_remove (password_cache, msg->key);
+ if (error != NULL)
+ g_propagate_error (&msg->error, error);
+
e_uri_free (uri);
}
#endif
@@ -634,17 +679,21 @@
{
GList *passwords;
EUri *uri;
+ GError *error = NULL;
uri = ep_keyring_uri_new (msg->key);
g_return_if_fail (uri != NULL);
/* Find all Evolution passwords matching the URI and delete them. */
- passwords = ep_keyring_lookup_passwords (uri->user, uri->host);
+ passwords = ep_keyring_lookup_passwords (uri->user, uri->host, &error);
if (passwords != NULL) {
- ep_keyring_delete_passwords (uri->user, uri->host, passwords);
+ ep_keyring_delete_passwords (uri->user, uri->host, passwords, &error);
gnome_keyring_found_list_free (passwords);
}
+ if (error != NULL)
+ g_propagate_error (&msg->error, error);
+
e_uri_free (uri);
}
#endif
@@ -672,11 +721,8 @@
g_message ("%s", error->message);
g_error_free (error);
- /* Issue a warning if anything else goes wrong. */
- } else if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
+ } else if (error != NULL)
+ g_propagate_error (&msg->error, error);
g_free (group);
g_free (key);
@@ -706,12 +752,13 @@
{
GList *passwords;
EUri *uri;
+ GError *error = NULL;
uri = ep_keyring_uri_new (msg->key);
g_return_if_fail (uri != NULL);
/* Find the first Evolution password that matches the URI. */
- passwords = ep_keyring_lookup_passwords (uri->user, uri->host);
+ passwords = ep_keyring_lookup_passwords (uri->user, uri->host, &error);
if (passwords != NULL) {
GList *iter = passwords;
@@ -729,6 +776,15 @@
gnome_keyring_found_list_free (passwords);
}
+ /* Not finding the requested key is acceptable, but we still
+ * want to leave an informational message on the terminal. */
+ if (g_error_matches (error, EP_KEYRING_ERROR, GNOME_KEYRING_RESULT_NO_MATCH)) {
+ g_message ("%s", error->message);
+ g_error_free (error);
+
+ } else if (error != NULL)
+ g_propagate_error (&msg->error, error);
+
e_uri_free (uri);
}
#endif
@@ -758,16 +814,40 @@
g_message ("%s", error->message);
g_error_free (error);
- /* Issue a warning if anything else goes wrong. */
- } else if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
+ } else if (error != NULL)
+ g_propagate_error (&msg->error, error);
g_free (group);
g_free (key);
}
+#ifdef WITH_GNOME_KEYRING
+static void
+ep_keyring_migrate_from_keyfile (EPassMsg *msg)
+{
+ /* Fetch the password from the keyfile. */
+ ep_get_password_keyfile (msg);
+ if (msg->password == NULL)
+ return;
+
+ /* Add it to the in-memory cache. */
+ g_hash_table_insert (
+ password_cache, g_strdup (msg->key),
+ g_strdup (msg->password));
+
+ /* Remember it in the keyring. */
+ ep_remember_password_keyring (msg);
+
+ /* Remove it from the in-memory cache. */
+ g_hash_table_remove (password_cache, msg->key);
+
+ /* Remove it from the keyfile only if the keyring
+ * insertion was successful. */
+ if (msg->error == NULL)
+ ep_forget_password_keyfile (msg);
+}
+#endif
+
static void
ep_get_password (EPassMsg *msg)
{
@@ -775,14 +855,19 @@
/* Check the in-memory cache first. */
password = g_hash_table_lookup (password_cache, msg->key);
- if (password != NULL)
+ if (password != NULL) {
msg->password = g_strdup (password);
#ifdef WITH_GNOME_KEYRING
- else if (gnome_keyring_is_available ())
+ } else if (gnome_keyring_is_available ()) {
ep_get_password_keyring (msg);
+
+ /* Try looking for the password in the keyfile.
+ * If we find it, migrate it to the keyring. */
+ if (msg->password == NULL && msg->error == NULL)
+ ep_keyring_migrate_from_keyfile (msg);
#endif
- else
+ } else
ep_get_password_keyfile (msg);
if (!msg->noreply)
@@ -1043,15 +1128,10 @@
(GDestroyNotify) g_free);
main_thread = g_thread_self ();
-#ifdef WITH_GNOME_KEYRING
- if (!gnome_keyring_is_available ()) {
- key_file = g_key_file_new ();
- ep_key_file_load ();
- }
-#else
+ /* Load the keyfile even if we're using the keyring.
+ * We might be able to extract passwords from it. */
key_file = g_key_file_new ();
ep_key_file_load ();
-#endif
}
G_UNLOCK (passwords);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]