soc.2008.masterpassword: db9aa842: Wrote a caching system that uses account...

scrouaf at soc.pidgin.im scrouaf at soc.pidgin.im
Sun Aug 17 02:11:06 EDT 2008


-----------------------------------------------------------------
Revision: db9aa84228006c5777c2e8469198955bd0c3c231
Ancestor: 7819ad38545e6988a5f8d898ab797c6521cd8965
Author: scrouaf at soc.pidgin.im
Date: 2008-08-17T01:28:28
Branch: im.pidgin.soc.2008.masterpassword
URL: http://d.pidgin.im/viewmtn/revision/info/db9aa84228006c5777c2e8469198955bd0c3c231

Modified files:
        libpurple/account.c libpurple/account.h libpurple/keyring.c
        libpurple/keyring.h
        libpurple/plugins/keyrings/gnomekeyring.c
        libpurple/plugins/keyrings/internalkeyring.c
        libpurple/protocols/gg/gg.c
        libpurple/protocols/jabber/auth.c
        libpurple/protocols/msn/contact.c
        libpurple/protocols/msn/msn.c libpurple/protocols/msn/page.c
        libpurple/protocols/msn/soap.c
        libpurple/protocols/qq/qq_network.c
        libpurple/protocols/sametime/sametime.c
        libpurple/protocols/silc/silc.c pidgin/gtkaccount.c

ChangeLog: 

Wrote a caching system that uses account->password to store password.
This means once they have been read once, they can be accessed directly,
even with sync accessors, without making a sync call to the keyring.
This also reduces communication with the keyring daemon.

Async calls are still made :
 - when a connection is created
 - when the password is asked or shown to the user (this regroups the password
request and account preferences forms).

An easy way to make sure all calls are async is to run :
  pidgin --debug |grep _sync_
Since all sync functions in both written keyrings will generate debut output
containing that string.

Reverted code from the prpls, since they access the passwords only once the
connection has been created. This makes them simpler to write and understand,
and makes them less bug prone.

I'm now going going to make the same changes to finch that I made to pidgin,
then will start the cleanup phase.

-------------- next part --------------
============================================================
--- libpurple/account.c	cdc8bc81e795ab250749fdd8a85a0176efdac36a
+++ libpurple/account.c	f3e650479b9aa90305308bfa2355de9e3500eddd
@@ -110,11 +110,11 @@ static void purple_account_connect_got_p
 
 static void purple_account_connect_got_password_cb(PurpleAccount * account,
        gchar * password, GError * error, gpointer data);
-static void request_password_ok_cb_continue(const PurpleAccount * account, 
-	GError * error,	gpointer data);
 
 static void purple_account_get_password_async_finish(PurpleAccount * account,
 	char * password, GError * error, gpointer data);
+
+static void purple_accounts_delete_finish(PurpleAccount * account, GError * error, gpointer data);
 /*********************************************************************
  * Writing to disk                                                   *
  *********************************************************************/
@@ -819,8 +819,8 @@ parse_account(xmlnode *node)
 	xmlnode *child;
 	char *protocol_id = NULL;
 	char *name = NULL;
-	char *keyring_id = NULL;
-	char *mode = NULL;
+	const char *keyring_id = NULL;
+	const char *mode = NULL;
 	char *data = NULL;
 	gboolean result = FALSE;
 	GError * error = NULL;
@@ -936,16 +936,11 @@ parse_account(xmlnode *node)
 
 		if (result == TRUE) {
 			purple_debug_info("accounts", "password imported successfully.\n");
-			purple_account_set_remember_password(ret, TRUE);
-			/*
-			g_free(keyring_id);	TODO :
-			g_free(mode);		This was commented becaus eof a double free.
-			g_free(data); 		I should figure out which one causes the bug to avoid leaks
-			*/
+			purple_account_set_remember_password(ret, TRUE);		
 		} else {
 			purple_debug_info("accounts", "failed to imported password.\n");
-			/* TODO handle error */
-		}
+		} 
+		g_free(data); 
 	}
 
 	return ret;
@@ -1118,28 +1113,26 @@ purple_account_register_got_password_cb(
 {
 	g_return_if_fail(account != NULL);
 
-	/* FIXME : handle error properly */
- 
 	purple_connection_new(account, TRUE, password);
 }
 
-struct _unregister_data
+typedef struct
 {
 	PurpleAccountUnregistrationCb cb;
 	void *user_data;
-};
+} UnregisterData;
 
 void
 purple_account_unregister(PurpleAccount *account, PurpleAccountUnregistrationCb cb, void *user_data)
 {
-	struct _unregister_data * data;
+	UnregisterData * data;
 
 	g_return_if_fail(account != NULL);
 
 	purple_debug_info("account", "Unregistering account %s\n",
 					  purple_account_get_username(account));
 
-	data = g_malloc(sizeof(struct _unregister_data));
+	data = g_new0(UnregisterData, 1);
 	data->cb = cb;
 	data->user_data = user_data;
 
@@ -1150,21 +1143,25 @@ purple_account_unregister_got_password_c
 static void
 purple_account_unregister_got_password_cb(PurpleAccount * account, char * password, GError * error, gpointer data)
 {
-	struct _unregister_data * unregdata;
-
+	UnregisterData * unregdata;
+	
 	g_return_if_fail(account != NULL);
 
 	/* FIXME : handle error properly */
 
 	unregdata = data;
+	g_return_if_fail(unregdata != NULL);
+
 	purple_connection_new_unregister(account, password, unregdata->cb, unregdata->user_data);
-}
 
+	g_free(unregdata);
+}
 
 static void
 request_password_ok_cb(PurpleAccount *account, PurpleRequestFields *fields)
 {
 	const char *entry;
+	char * password;
 	gboolean remember;
 
 	entry = purple_request_fields_get_string(fields, "password");
@@ -1181,23 +1178,14 @@ request_password_ok_cb(PurpleAccount *ac
 
 	purple_account_set_remember_password(account, remember);
 
-	purple_account_set_password(account, entry);
+	password = g_strdup(entry);
+	purple_account_set_password(account, password);
+	g_free(password);
 	purple_connection_new(account, FALSE, entry);
 
 }
 
 static void
-request_password_ok_cb_continue(const PurpleAccount * account, 
-				GError * error,
-				gpointer data)
-{
-	char * password = data;
-
-	purple_connection_new(account, FALSE, password);
-	g_free(password);
-}
-
-static void
 request_password_cancel_cb(PurpleAccount *account, PurpleRequestFields *fields)
 {
 	/* Disable the account as the user has canceled connecting */
@@ -1251,7 +1239,6 @@ purple_account_connect(PurpleAccount *ac
 {
 	PurplePlugin *prpl;
 	PurplePluginProtocolInfo *prpl_info;
-	const char *password;
 
 	g_return_if_fail(account != NULL);
 
@@ -1632,7 +1619,7 @@ void
 }
 
 void
-purple_account_set_password(PurpleAccount *account, const char *password)
+purple_account_set_password(PurpleAccount *account, char *password)
 {
 	schedule_accounts_save();
 
@@ -1644,7 +1631,7 @@ purple_account_set_password(PurpleAccoun
 	account->password = g_strdup(password);
 
 	if (purple_account_get_remember_password(account) == TRUE)
-		purple_keyring_set_password_sync(account, password);
+		purple_keyring_set_password_async(account, password, NULL, NULL, NULL);
 }
 
 void 
@@ -1658,30 +1645,28 @@ purple_account_set_password_async(Purple
 	 * This is so we can force an account sync by calling
 	 * it with account == NULL.
 	 */
-	if(account != NULL) {
+	schedule_accounts_save();
 
-		if (account->password != NULL)
-			g_free(account->password);
-		account->password = g_strdup(password);
+	g_return_if_fail(account != NULL);
 
-		if (purple_account_get_remember_password(account) == FALSE) {
+	if (account->password != NULL)
+		g_free(account->password);
+	account->password = g_strdup(password);
 
-			account->password = g_strdup(password);
-			purple_debug_info("account",
-				"Password for %s set, not sent to keyring.\n",
-				purple_account_get_username(account));
+	if (purple_account_get_remember_password(account) == FALSE) {
 
-			if (cb != NULL)
-				cb(account, NULL, data);
+		account->password = g_strdup(password);
+		purple_debug_info("account",
+			"Password for %s set, not sent to keyring.\n",
+			purple_account_get_username(account));
 
-		} else {
+		if (cb != NULL)
+			cb(account, NULL, data);
 
-			purple_keyring_set_password_async(account, password,
-				destroypassword, cb, data);
-
-		}
+	} else {
+		purple_keyring_set_password_async(account, password,
+			destroypassword, cb, data);
 	}
-	schedule_accounts_save();
 }
 void
 purple_account_set_alias(PurpleAccount *account, const char *alias)
@@ -2103,12 +2088,15 @@ purple_account_get_password_async(Purple
 				  PurpleKeyringReadCallback cb,
 				  gpointer data)
 {
-	char * password;
-
 	CbInfo * info = g_new0(CbInfo,1);
 	info->cb = cb;
 	info->data = data;
 
+	if(account == NULL) {
+		cb(NULL, NULL, NULL, data);
+		return;
+	}
+
 	if (account->password != NULL) {
 		purple_debug_info("accounts",
 			"Reading password for account %s (%s) from cached (async).\n",
@@ -2122,7 +2110,7 @@ purple_account_get_password_async(Purple
 			purple_account_get_username(account),
 			purple_account_get_protocol_id(account));
 		purple_keyring_get_password_async(account, 
-			purple_account_get_password_async_finish, data);
+			purple_account_get_password_async_finish, info);
 	}
 }
 
@@ -2135,6 +2123,8 @@ purple_account_get_password_async_finish
 	CbInfo * info;
 	PurpleKeyringReadCallback cb;
 
+	
+
 	purple_debug_info("accounts",
 		"Read password for account %s (%s) from async keyring.\n",
 		purple_account_get_username(account),
@@ -2143,9 +2133,9 @@ purple_account_get_password_async_finish
 	info = data;
 
 	g_return_if_fail(account != NULL);
-	g_return_if_fail(info != NULL);
-
+	g_free(account->password);
 	account->password = g_strdup(password);
+	g_return_if_fail(info != NULL);
 
 	cb = info->cb;
 	if (cb != NULL)
@@ -2803,9 +2793,20 @@ purple_accounts_delete(PurpleAccount *ac
 	/* This will cause the deletion of an old buddy icon. */
 	purple_buddy_icons_set_account_icon(account, NULL, 0);
 
-	purple_account_destroy(account);
+	/* this is async because we do not want the
+	 * account overwritten before we are done.
+	 */
+	purple_keyring_set_password_async(account, NULL, NULL, 
+		purple_accounts_delete_finish, NULL);
+
 }
 
+static void
+purple_accounts_delete_finish(PurpleAccount * account, GError * error, gpointer data)
+{
+		purple_account_destroy(account);
+}
+
 void
 purple_accounts_reorder(PurpleAccount *account, gint new_index)
 {
============================================================
--- libpurple/account.h	3ab4e92017f078e6e951d1f86d8c4f0f89a6ec72
+++ libpurple/account.h	fbac72f02a9e773c9275f7fb8871b017c163fefd
@@ -328,7 +328,7 @@ void purple_account_set_username(PurpleA
  * @param account  The account.
  * @param password The password.
  */
-void purple_account_set_password(PurpleAccount *account, const char *password)  __attribute__ ((deprecated));
+void purple_account_set_password(PurpleAccount *account, char *password)  __attribute__ ((deprecated));
 
 /**
  * Set a password to be remembered.
============================================================
--- libpurple/keyring.c	8895b9a5a71036218c0582262962d3b9baea9ff7
+++ libpurple/keyring.c	156b33dcbfc3c0d5c5887deb7b8003b29e5ba7fd
@@ -42,6 +42,7 @@ static void purple_keyring_set_inuse_got
 static void purple_keyring_drop_passwords(const PurpleKeyring * keyring);
 static void purple_keyring_set_inuse_check_error_cb(const PurpleAccount *,GError *,gpointer);
 static void purple_keyring_set_inuse_got_pw_cb(PurpleAccount *, gchar *, GError *, gpointer);
+static void purple_keyring_set_password_async_cb(PurpleAccount * account, GError * error, gpointer data);
 
 
 /******************************************/
@@ -799,9 +800,9 @@ purple_keyring_import_password(PurpleAcc
 
 gboolean
 purple_keyring_import_password(PurpleAccount * account, 
-			       char * keyringid,
-			       char * mode,
-			       char * data,
+			       const char * keyringid,
+			       const char * mode,
+			       const char * data,
 			       GError ** error)
 {
 	const PurpleKeyring * inuse;
@@ -974,57 +975,44 @@ purple_keyring_set_password_async(const 
 	PurpleKeyringSave save;
 	PurpleKeyringCbInfo * cbinfo;
 
-	if (account == NULL) {
-		error = g_error_new(ERR_PIDGINKEYRING, ERR_INVALID,
-			"No account passed to the function.");
+	g_return_if_fail(account != NULL);
 
+	inuse = purple_keyring_get_inuse();
+	if (inuse == NULL) {
+		error = g_error_new(ERR_PIDGINKEYRING, ERR_NOKEYRING,
+			"No keyring configured.");
 		if (cb != NULL)
 			cb(account, error, data);
-
 		g_error_free(error);
 
 	} else {
-		inuse = purple_keyring_get_inuse();
-
-		if (inuse == NULL) {
-			error = g_error_new(ERR_PIDGINKEYRING, ERR_NOKEYRING,
-				"No keyring configured.");
-
+		save = purple_keyring_get_save_password(inuse);
+		if (save == NULL) {
+			error = g_error_new(ERR_PIDGINKEYRING, ERR_NOCAP,
+				"Keyring cannot save password.");
 			if (cb != NULL)
 				cb(account, error, data);
-
 			g_error_free(error);
 
 		} else {
-			save = purple_keyring_get_save_password(inuse);
-
-			if (save == NULL) {
-				error = g_error_new(ERR_PIDGINKEYRING, ERR_NOCAP,
-					"Keyring cannot save password.");
-
-				if (cb != NULL)
-					cb(account, error, data);
-
-				g_error_free(error);
-
-			} else {
-				cbinfo = g_malloc(sizeof(PurpleKeyringCbInfo));
-				cbinfo->cb = cb;
-				cbinfo->data = data;
-				save(account, password, destroypassword,
-					purple_keyring_set_password_async, data);
-			}
+			cbinfo = g_malloc(sizeof(PurpleKeyringCbInfo));
+			cbinfo->cb = cb;
+			cbinfo->data = data;
+			save(account, password, destroypassword,
+				purple_keyring_set_password_async_cb, data);
 		}
 	}
-
 	return;
 }
 
-void 
+static void 
 purple_keyring_set_password_async_cb(PurpleAccount * account, 
 				     GError * error,
 				     gpointer data)
 {
+	g_return_if_fail(data != NULL);
+	g_return_if_fail(account != NULL);
+
 	PurpleKeyringCbInfo * cbinfo = data;
 	PurpleKeyringSaveCallback cb = cbinfo->cb;
 
@@ -1048,7 +1036,7 @@ purple_keyring_get_password_sync(const P
 
 	g_return_val_if_fail(account != NULL, NULL);
 
-	purple_debug_info("keyring (sync)",
+	purple_debug_info("keyring (_sync_)",
 		"Reading password for account %s (%s)",
 		purple_account_get_username(account),
 		purple_account_get_protocol_id(account));
@@ -1078,7 +1066,7 @@ purple_keyring_set_password_sync(PurpleA
 	PurpleKeyringSaveSync save;
 	const PurpleKeyring * inuse;
 
-	purple_debug_info("keyring (sync)",
+	purple_debug_info("keyring (_sync_)",
 		"Setting password for account %s (%s)",
 		purple_account_get_username(account),
 		purple_account_get_protocol_id(account));
============================================================
--- libpurple/keyring.h	92683f2239191f94c9de4e3077bb3fa0bed905d0
+++ libpurple/keyring.h	291fa07f017f9f51ee37158cd0ec29133629dce4
@@ -186,8 +186,8 @@ typedef gboolean (*PurpleKeyringImportPa
  * @return TRUE on success, FALSE on failure.
  */
 typedef gboolean (*PurpleKeyringImportPassword)(PurpleAccount * account, 
-					    char * mode,
-					    char * data,
+					    const char * mode,
+					    const char * data,
 					    GError ** error);
 
 /**
@@ -302,9 +302,9 @@ gboolean purple_keyring_import_password(
  * @return TRUE if the input was accepted, FALSE otherwise.
  */
 gboolean purple_keyring_import_password(PurpleAccount * account, 
-				    char * keyringid,
-				    char * mode,
-				    char * data,
+				    const char * keyringid,
+				    const char * mode,
+				    const char * data,
 				    GError ** error);
 
 /**
============================================================
--- libpurple/plugins/keyrings/gnomekeyring.c	65ab054c4682c4ed72dd91be818ecf2dfea73b96
+++ libpurple/plugins/keyrings/gnomekeyring.c	7f9f6f7cc2c008611a362eefd9df1c2c3c66d840
@@ -72,6 +72,7 @@ struct _InfoStorage
 	gpointer cb;
 	gpointer user_data;
 	PurpleAccount * account;
+	char * name;
 };
 
 
@@ -80,13 +81,13 @@ static void 		gkp_read(PurpleAccount *, 
 /* a few prototypes : */
 static GQuark 		gkp_error_domain(void);
 static void 		gkp_read(PurpleAccount *, PurpleKeyringReadCallback, gpointer);
-static void		gkp_read_continue(GnomeKeyringResult, char *, gpointer);
+static void		gkp_read_continue(GnomeKeyringResult, const char *, gpointer);
 static void 		gkp_save(PurpleAccount *, gchar *, GDestroyNotify, PurpleKeyringSaveCallback, gpointer);
 static void		gkp_save_continue(GnomeKeyringResult, gpointer);
 static const char * 	gkp_read_sync(const PurpleAccount *);
 static void 		gkp_save_sync(PurpleAccount *, const gchar *);
 static void		gkp_close(GError **);
-static gboolean		gkp_import_password(PurpleAccount *, char *, char *, GError **);
+static gboolean		gkp_import_password(PurpleAccount *, const char *, const char *, GError **);
 static gboolean 	gkp_export_password(PurpleAccount *, const char **, char **, GError **, GDestroyNotify *);
 static gboolean		gkp_init(void);
 static void		gkp_uninit(void);
@@ -124,7 +125,7 @@ static void gkp_read_continue(GnomeKeyri
 }
 
 static void gkp_read_continue(GnomeKeyringResult result,
-                       char *password,
+                       const char *password,
                        gpointer data)
 /* XXX : make sure list is freed on return */
 {
@@ -132,6 +133,7 @@ static void gkp_read_continue(GnomeKeyri
 	PurpleAccount * account =storage->account;
 	PurpleKeyringReadCallback cb = storage->cb;
 	GError * error;
+	char * copy;
 
 	if (result != GNOME_KEYRING_RESULT_OK) {
 
@@ -168,12 +170,13 @@ static void gkp_read_continue(GnomeKeyri
 
 	} else {
 
-		if(cb != NULL)
-			cb(account, password, NULL, storage->user_data);
+		if(cb != NULL) {
+			copy = g_strdup(password);
+			cb(account, copy, NULL, storage->user_data);
+			g_free(copy);
+		}
 		return;
-
 	}
-
 }
 
 
@@ -185,13 +188,15 @@ gkp_save(PurpleAccount * account,
 	 gpointer data)
 {
 	/* FIXME : the name will leak */
-	InfoStorage * storage = g_malloc(sizeof(InfoStorage));
+	InfoStorage * storage = g_new0(InfoStorage,1);
 
 	storage->account = account;
 	storage->cb = cb;
 	storage->user_data = data;
+	storage->name = g_strdup_printf("pidgin-%s",
+		purple_account_get_username(account));
 
-	if(password != NULL && *password != '\O') {
+	if(password != NULL && *password != '\0') {
 
 		purple_debug_info("Gnome keyring plugin",
 			"Updating password for account %s (%s).\n",
@@ -200,7 +205,7 @@ gkp_save(PurpleAccount * account,
 
 		gnome_keyring_store_password(GNOME_KEYRING_NETWORK_PASSWORD,
 					     NULL, 	/*default keyring */
-					     g_strdup_printf("pidgin-%s", purple_account_get_username(account)),
+					     storage->name,
 					     password,
 		                             gkp_save_continue,
 					     storage,
@@ -235,13 +240,19 @@ gkp_save_continue(GnomeKeyringResult res
 gkp_save_continue(GnomeKeyringResult result,
             gpointer data)
 {
-	InfoStorage * storage = data;
-	PurpleKeyringSaveCallback cb = storage->cb;
+	InfoStorage * storage;
+	PurpleKeyringSaveCallback cb;
 	GError * error;
-	PurpleAccount * account = storage->account;
+	PurpleAccount * account;
 
+	storage = data;
 	g_return_if_fail(storage != NULL);
 
+	cb = storage->cb;
+	account = storage->account;
+	
+	g_free(storage->name);
+
 	if (result != GNOME_KEYRING_RESULT_OK) {
 		switch(result)
 		{
@@ -313,6 +324,9 @@ gkp_read_sync(const PurpleAccount * acco
 	GnomeKeyringResult result;
 	static char * password = NULL;
 
+	purple_debug_info("Gnome-Keyring plugin (_sync_)", "password for %s was read.\n",
+			purple_account_get_username(account));
+
 	gnome_keyring_free_password(password);
 
 	result = gnome_keyring_find_password_sync(GNOME_KEYRING_NETWORK_PASSWORD,
@@ -325,12 +339,12 @@ static void
 }
 
 static void
-gkp_save_sync(PurpleAccount * account,
+gkp_save_sync(PurpleAccount * account, 
 	const char * password)
 {
 	const char * name;
 
-	if(password != NULL && *password != '\O') {
+	if(password != NULL && *password != '\0') {
 
 		name =g_strdup_printf("pidgin-%s", purple_account_get_username(account)),
 
@@ -339,7 +353,7 @@ gkp_save_sync(PurpleAccount * account,
 			"user", purple_account_get_username(account),
 			"protocol", purple_account_get_protocol_id(account),
 			NULL);
-		purple_debug_info("GnomeKeyring plugin (sync)", 
+		purple_debug_info("GnomeKeyring plugin (_sync_)", 
 			"Updated password for account %s (%s).\n",
 			purple_account_get_username(account),
 			purple_account_get_protocol_id(account));
@@ -349,7 +363,7 @@ gkp_save_sync(PurpleAccount * account,
 			"user", purple_account_get_username(account),
 			"protocol", purple_account_get_protocol_id(account),
 			NULL);
-		purple_debug_info("GnomeKeyring plugin (sync)", 
+		purple_debug_info("GnomeKeyring plugin (_sync_)", 
 			"Deleted password for account %s (%s).\n",
 			purple_account_get_username(account),
 			purple_account_get_protocol_id(account));
@@ -365,8 +379,8 @@ gkp_import_password(PurpleAccount * acco
 
 static gboolean
 gkp_import_password(PurpleAccount * account, 
-		    char * mode,
-		    char * data,
+		    const char * mode,
+		    const char * data,
 		    GError ** error)
 {
 	purple_debug_info("Gnome Keyring plugin",
============================================================
--- libpurple/plugins/keyrings/internalkeyring.c	54987c1ac094525a5a1bc5276041c1c625416855
+++ libpurple/plugins/keyrings/internalkeyring.c	66aaf2d96c9b726e0bcb68d13bda37a8053fe1a9
@@ -78,7 +78,7 @@ static void		internal_keyring_open(void)
 static void 		internal_keyring_save_sync(PurpleAccount *, const gchar *);
 static void		internal_keyring_close(GError **);
 static void		internal_keyring_open(void);
-static gboolean		internal_keyring_import_password(PurpleAccount *, char *, char *, GError **);
+static gboolean		internal_keyring_import_password(PurpleAccount *, const char *, const char *, GError **);
 static gboolean 	internal_keyring_export_password(PurpleAccount *, const char **, char **, GError **, GDestroyNotify *);
 static void		internal_keyring_init(void);
 static void		internal_keyring_uninit(void);
@@ -160,7 +160,7 @@ internal_keyring_read_sync(const PurpleA
 {
 	ACTIVATE();
 
-	purple_debug_info("Internal Keyring (sync)", 
+	purple_debug_info("Internal Keyring (_sync_)", 
 		"Password for %s (%s) was read.\n",
 		purple_account_get_username(account),
 		purple_account_get_protocol_id(account));
@@ -176,16 +176,16 @@ internal_keyring_save_sync(PurpleAccount
 
 	ACTIVATE();
 
-	if (password == NULL || *password == '\O') {
+	if (password == NULL || *password == '\0') {
 		g_hash_table_remove(internal_keyring_passwords, account);
-		purple_debug_info("Internal Keyring (sync)", 
+		purple_debug_info("Internal Keyring (_sync_)", 
 			"Password for %s (%s) was deleted.\n",
 			purple_account_get_username(account),
 			purple_account_get_protocol_id(account));
 	} else {
 		copy = g_strdup(password);
 		SET_PASSWORD(account, copy);
-		purple_debug_info("Internal Keyring (sync)", 
+		purple_debug_info("Internal Keyring (_sync_)", 
 			"Password for %s (%s) was set.\n",
 			purple_account_get_username(account),
 			purple_account_get_protocol_id(account));
@@ -213,8 +213,8 @@ internal_keyring_import_password(PurpleA
 
 static gboolean
 internal_keyring_import_password(PurpleAccount * account, 
-				 char * mode,
-				 char * data,
+				 const char * mode,
+				 const char * data,
 				 GError ** error)
 {
 	gchar * copy;
@@ -262,7 +262,8 @@ internal_keyring_export_password(PurpleA
 	 * lead to exporting uninitialised data, which 
 	 * we obviously don't want.
 	 */
-	password = purple_account_get_password(account);
+	//password = purple_account_get_password(account);
+	password = GET_PASSWORD(account);
 
 	if (password == NULL) {
 		return FALSE;
============================================================
--- libpurple/protocols/gg/gg.c	2c7f14995fdb050d2c6b585d6aa3d17f62b33e81
+++ libpurple/protocols/gg/gg.c	3541ee65317e2d346e4e478792f99829dd6d2f26
@@ -676,41 +676,12 @@ static void ggp_find_buddies(PurplePlugi
 
 /* ----- CHANGE PASSWORD ------------------------------------------------ */
 
-typedef struct _ConnectionCallbackData
-{
-	PurpleConnection *gc;
-	PurpleRequestFields *fields;
-} ConnectionCallbackData;
-
-
 /*
  */
 /* static void ggp_callback_change_passwd_ok(PurpleConnection *gc, PurpleRequestFields *fields) {{{ */
-static void ggp_callback_change_passwd_ok_continue(PurpleAccount * account,
-	gchar * password, GError * error, gpointer user_data);
-
 static void ggp_callback_change_passwd_ok(PurpleConnection *gc, PurpleRequestFields *fields)
 {
-	ConnectionCallbackData *data;
 	PurpleAccount *account;
-
-       	data = g_new(ConnectionCallbackData, 1);
-	account = purple_connection_get_account(gc);
-
-	data->gc = gc;
-	data->fields = fields;
-
-	purple_account_get_password_async(account, ggp_callback_change_passwd_ok_continue, data);
-}
-
-static void ggp_callback_change_passwd_ok_continue(PurpleAccount * account,
-					  gchar * password,
-					  GError * error,
-					  gpointer user_data)
-{
-	ConnectionCallbackData *data = user_data;
-	PurpleConnection *gc = data->gc;
-	PurpleRequestFields *fields = data->fields;
 	GGPInfo *info = gc->proto_data;
 	struct gg_http *h;
 	gchar *cur, *p1, *p2, *t;
@@ -742,7 +713,7 @@ static void ggp_callback_change_passwd_o
 		goto exit_err;
 	}
 
-	if (g_utf8_collate(cur, password) != 0) {
+	if (g_utf8_collate(cur, purple_account_get_password(account)) != 0) {
 		purple_notify_error(account, NULL,
 			_("Your current password is different from the one that you specified."),
 			NULL);
@@ -753,7 +724,7 @@ static void ggp_callback_change_passwd_o
 
 	/* XXX: this email should be a pref... */
 	h = gg_change_passwd4(ggp_get_uin(account),
-			      "user at example.net", password,
+			      "user at example.net", purple_account_get_password(account),
 			      p1, info->token->id, t, 0);
 
 	if (h == NULL) {
@@ -1714,18 +1685,8 @@ static GList *ggp_chat_info(PurpleConnec
 /* }}} */
 
 /* static void ggp_login(PurpleAccount *account) {{{ */
-static void ggp_login_continue(PurpleAccount *account, gchar * password, GError * error, gpointer data);
-
 static void ggp_login(PurpleAccount *account)
 {
-	purple_account_get_password_async(account, ggp_login_continue, NULL);
-}
-
-static void ggp_login_continue(PurpleAccount *account,
-			       gchar * password,
-			       GError * error,
-			       gpointer data)
-{
 	PurpleConnection *gc;
 	PurplePresence *presence;
 	PurpleStatus *status;
@@ -1749,7 +1710,7 @@ static void ggp_login_continue(PurpleAcc
 	gc->proto_data = info;
 
 	glp->uin = ggp_get_uin(account);
-	glp->password = password;
+	glp->password = (char *)purple_account_get_password(account);
 
 	presence = purple_account_get_presence(account);
 	status = purple_presence_get_active_status(presence);
============================================================
--- libpurple/protocols/jabber/auth.c	a73b3f570892edfa782aa6e17808b8d20e1f6ae8
+++ libpurple/protocols/jabber/auth.c	3edd7f889379139a3fb0da6e9a0810c224b54384
@@ -25,7 +25,6 @@
 #include "cipher.h"
 #include "core.h"
 #include "conversation.h"
-#include "keyring.h"
 #include "request.h"
 #include "sslconn.h"
 #include "util.h"
@@ -66,78 +65,52 @@ jabber_process_starttls(JabberStream *js
 	return FALSE;
 }
 
-static void finish_plaintext_authentication_continue_plain(PurpleAccount * account,
-	char * password, GError * error, gpointer data);
-static void finish_plaintext_authentication_continue_iq_auth(PurpleAccount * account,
-	char * password, GError * error, gpointer data);
-
 static void finish_plaintext_authentication(JabberStream *js)
 {
 	if(js->auth_type == JABBER_AUTH_PLAIN) {
-		 purple_connection_get_password_async(js->gc,
-			finish_plaintext_authentication_continue_plain, js);
+		xmlnode *auth;
+		GString *response;
+		gchar *enc_out;
 
-	} else if(js->auth_type == JABBER_AUTH_IQ_AUTH) {
-		purple_account_get_password_async(js->gc,
-			finish_plaintext_authentication_continue_iq_auth, js);
-	}
-}
+		auth = xmlnode_new("auth");
+		xmlnode_set_namespace(auth, "urn:ietf:params:xml:ns:xmpp-sasl");
 
-static void finish_plaintext_authentication_continue_plain(PurpleAccount * account,
-							   char * password,
-							   GError * error,
-							   gpointer data)
-{
-	xmlnode *auth;
-	GString *response;
-	gchar *enc_out;
-	JabberStream *js = data;
+		xmlnode_set_attrib(auth, "xmlns:ga", "http://www.google.com/talk/protocol/auth");
+		xmlnode_set_attrib(auth, "ga:client-uses-full-bind-result", "true");
 
-	auth = xmlnode_new("auth");
-	xmlnode_set_namespace(auth, "urn:ietf:params:xml:ns:xmpp-sasl");
+		response = g_string_new("");
+		response = g_string_append_len(response, "\0", 1);
+		response = g_string_append(response, js->user->node);
+		response = g_string_append_len(response, "\0", 1);
+		response = g_string_append(response,
+				purple_connection_get_password(js->gc));
 
-	xmlnode_set_attrib(auth, "xmlns:ga", "http://www.google.com/talk/protocol/auth");
-	xmlnode_set_attrib(auth, "ga:client-uses-full-bind-result", "true");
+		enc_out = purple_base64_encode((guchar *)response->str, response->len);
 
-	response = g_string_new("");
-	response = g_string_append_len(response, "\0", 1);
-	response = g_string_append(response, js->user->node);
-	response = g_string_append_len(response, "\0", 1);
-	response = g_string_append(response,
-			purple_connection_get_password(js->gc));
+		xmlnode_set_attrib(auth, "mechanism", "PLAIN");
+		xmlnode_insert_data(auth, enc_out, -1);
+		g_free(enc_out);
+		g_string_free(response, TRUE);
 
-	enc_out = purple_base64_encode((guchar *)response->str, response->len);
+		jabber_send(js, auth);
+		xmlnode_free(auth);
+	} else if(js->auth_type == JABBER_AUTH_IQ_AUTH) {
+		JabberIq *iq;
+		xmlnode *query, *x;
 
-	xmlnode_set_attrib(auth, "mechanism", "PLAIN");
-	xmlnode_insert_data(auth, enc_out, -1);
-	g_free(enc_out);
-	g_string_free(response, TRUE);
-
-	jabber_send(js, auth);
-	xmlnode_free(auth);
+		iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
+		query = xmlnode_get_child(iq->node, "query");
+		x = xmlnode_new_child(query, "username");
+		xmlnode_insert_data(x, js->user->node, -1);
+		x = xmlnode_new_child(query, "resource");
+		xmlnode_insert_data(x, js->user->resource, -1);
+		x = xmlnode_new_child(query, "password");
+		xmlnode_insert_data(x, purple_connection_get_password(js->gc), -1);
+		jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
+		jabber_iq_send(iq);
+	}
 }
 
-static void finish_plaintext_authentication_continue_iq_auth(PurpleAccount * account,
-							     char * password,
-							     GError * error,
-							     gpointer data)
-{
-	JabberIq *iq;
-	xmlnode *query, *x;
-	JabberStream *js = data;
-
-	iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
-	query = xmlnode_get_child(iq->node, "query");
-	x = xmlnode_new_child(query, "username");
-	xmlnode_insert_data(x, js->user->node, -1);
-	x = xmlnode_new_child(query, "resource");
-	xmlnode_insert_data(x, js->user->resource, -1);
-	x = xmlnode_new_child(query, "password");
-	xmlnode_insert_data(x, password, -1);
-	jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
-	jabber_iq_send(iq);
-}
-
 static void allow_plaintext_auth(PurpleAccount *account)
 {
 	purple_account_set_bool(account, "auth_plain_in_clear", TRUE);
============================================================
--- libpurple/protocols/msn/contact.c	5ba5a695c8bb6f77891a8662b624566bd1d3589b
+++ libpurple/protocols/msn/contact.c	74dcd9e76be5e13e3846fade00d5230d33262151
@@ -214,6 +214,7 @@ msn_create_address_book(MsnSession *sess
 msn_create_address_book(MsnSession *session)
 {
 	gchar *body;
+	gchar *token_str;
 
 	g_return_if_fail(session != NULL);
 	g_return_if_fail(session->user != NULL);
@@ -221,9 +222,11 @@ msn_create_address_book(MsnSession *sess
 	
 	purple_debug_info("msn", "Creating an Address Book.\n");
 
-	body = purple_markup_printf_escaped(MSN_ADD_ADDRESSBOOK_TEMPLATE,
-		msn_nexus_get_token_str(session->nexus, MSN_AUTH_CONTACTS),
-		session->user->passport);
+	token_str = g_markup_escape_text(
+		msn_nexus_get_token_str(session->nexus, MSN_AUTH_CONTACTS), -1);
+	body = g_strdup_printf(MSN_ADD_ADDRESSBOOK_TEMPLATE,
+		token_str, session->user->passport);
+	g_free(token_str);
 
 	msn_soap_message_send(session,
 		msn_soap_message_new(MSN_ADD_ADDRESSBOOK_SOAP_ACTION,
@@ -398,6 +401,7 @@ msn_get_contact_list(MsnSession *session
 {
 	gchar *body = NULL;
 	gchar *update_str = NULL;
+	gchar *token_str;
 	GetContactListCbData cb_data = { session, partner_scenario };
 	const gchar *partner_scenario_str = MsnSoapPartnerScenarioText[partner_scenario];
 
@@ -405,12 +409,14 @@ msn_get_contact_list(MsnSession *session
 
 	if (update_time != NULL) {
 		purple_debug_info("msn", "CL Last update time: %s\n", update_time);
-		update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML,update_time);
+		update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML, update_time);
 	}
 
-	body = purple_markup_printf_escaped(MSN_GET_CONTACT_TEMPLATE, partner_scenario_str,
-		msn_nexus_get_token_str(session->nexus, MSN_AUTH_CONTACTS),
-		update_str ? update_str : "");
+	token_str = g_markup_escape_text(
+		msn_nexus_get_token_str(session->nexus, MSN_AUTH_CONTACTS), -1);
+	body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, partner_scenario_str,
+		token_str, update_str ? update_str : "");
+	g_free(token_str);
 
 	msn_soap_message_send(session,
 		msn_soap_message_new(MSN_GET_CONTACT_SOAP_ACTION,
@@ -798,6 +804,7 @@ msn_get_address_book(MsnSession *session
 	const char *dynamicItemLastChange)
 {
 	char *body, *update_str = NULL;
+	gchar *token_str;
 
 	purple_debug_misc("msn", "Getting Address Book\n");
 
@@ -807,10 +814,13 @@ msn_get_address_book(MsnSession *session
 	else if (LastChanged != NULL)
 		update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, LastChanged);
 
-	body = purple_markup_printf_escaped(MSN_GET_ADDRESS_TEMPLATE,
+	token_str = g_markup_escape_text(
+		msn_nexus_get_token_str(session->nexus, MSN_AUTH_CONTACTS), -1);
+	body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE,
 		MsnSoapPartnerScenarioText[partner_scenario],
-		msn_nexus_get_token_str(session->nexus, MSN_AUTH_CONTACTS),
+		token_str,
 		update_str ? update_str : "");
+	g_free(token_str);
 
 	msn_soap_message_send(session,
 		msn_soap_message_new(MSN_GET_ADDRESS_SOAP_ACTION,
============================================================
--- libpurple/protocols/msn/msn.c	9a20e992d2605b5cbfb8bcfa771ca165458c54c2
+++ libpurple/protocols/msn/msn.c	5ec6d0ec264cfbe749d3f8cf49961463ffb01d94
@@ -713,10 +713,16 @@ msn_tooltip_text(PurpleBuddy *buddy, Pur
 		if (name != NULL && *name) {
 			char *tmp2;
 
+			tmp2 = g_markup_escape_text(name, -1);
 			if (purple_presence_is_idle(presence)) {
-				tmp2 = purple_markup_printf_escaped("%s/%s", name, _("Idle"));
-			} else {
-				tmp2 = g_markup_escape_text(name, -1);
+				char *idle;
+				char *tmp3;
+				/* Never know what those translations might end up like... */
+				idle = g_markup_escape_text(_("Idle"), -1);
+				tmp3 = g_strdup_printf("%s/%s", tmp2, idle);
+				g_free(idle);
+				g_free(tmp2);
+				tmp2 = tmp3;
 			}
 
 			if (psm != NULL && *psm) {
============================================================
--- libpurple/protocols/msn/page.c	2f6d4a5b23f2b7f45c6737486b11cf70ef097353
+++ libpurple/protocols/msn/page.c	ea4e9c550dcd213b5f3aaa8d6adc2047a00135b0
@@ -50,12 +50,15 @@ msn_page_gen_payload(const MsnPage *page
 msn_page_gen_payload(const MsnPage *page, size_t *ret_size)
 {
 	char *str;
+	char *body;
 
 	g_return_val_if_fail(page != NULL, NULL);
 
-	str = purple_markup_printf_escaped(
+	body = g_markup_escape_text(msn_page_get_body(page), -1);
+	str = g_strdup_printf(
 			"<TEXT xml:space=\"preserve\" enc=\"utf-8\">%s</TEXT>",
-			msn_page_get_body(page));
+			body);
+	g_free(body);
 
 	if (ret_size != NULL)
 		*ret_size = strlen(str);
============================================================
--- libpurple/protocols/msn/soap.c	1b15b2d3fe815fc30acae698d0a2ebd3e179897f
+++ libpurple/protocols/msn/soap.c	40dbab047960016ae96c77ffa8efc059eac0f40c
@@ -38,7 +38,7 @@
 #endif
 
 #define SOAP_TIMEOUT (5 * 60)
-#define MSN_UNSAFE_DEBUG 1
+
 typedef struct _MsnSoapRequest {
 	char *path;
 	MsnSoapMessage *message;
============================================================
--- libpurple/protocols/qq/qq_network.c	83570bf68fedc74884525549ea7617220c04e4a5
+++ libpurple/protocols/qq/qq_network.c	4364dbec36ac54db6ce17b68698173e582d596de
@@ -564,42 +564,16 @@ static gboolean network_timeout(gpointer
 
 /* the callback function after socket is built
  * we setup the qq protocol related configuration here */
-typedef struct _ConnectInfo
-{
-	PurpleConnection * gc;
-	gint source;
-	const gchar * error;
-} ConnectInfo;
-static void qq_connect_cb_continue(PurpleAccount * account, char * password, GError * error, gpointer data);
-
 static void qq_connect_cb(gpointer data, gint source, const gchar *error_message)
 {
-	ConnectInfo * info;
-	PurpleAccount * account;
-
-	info = g_malloc(sizeof(ConnectInfo));
-	info->gc = (PurpleConnection *) data;
-	info->source = source;
-	info->error =error_message;
-	
-	account = purple_connection_get_account(info->gc);
-
-	purple_account_get_password_async(account, qq_connect_cb_continue, info);
-
-	g_free(info);
-}
-static void qq_connect_cb_continue(PurpleAccount * account,
-				   char * passwd,
-				   GError * error,
-				   gpointer data)
-{
-	ConnectInfo * info = (ConnectInfo *)data;
-	gint source			= info->source;
-	const gchar *error_message	= info->error;
-	PurpleConnection *gc		= info->gc;
 	qq_data *qd;
+	PurpleConnection *gc;
 	gchar *conn_msg;
+	const gchar *passwd;
+	PurpleAccount *account ;
 
+	gc = (PurpleConnection *) data;
+
 	if (!PURPLE_CONNECTION_IS_VALID(gc)) {
 		purple_debug(PURPLE_DEBUG_INFO, "QQ_CONN", "Invalid connection\n");
 		close(source);
@@ -609,6 +583,7 @@ static void qq_connect_cb_continue(Purpl
 	g_return_if_fail(gc != NULL && gc->proto_data != NULL);
 
 	qd = (qq_data *) gc->proto_data;
+	account = purple_connection_get_account(gc);
 
 	/* Connect is now complete; clear the PurpleProxyConnectData */
 	qd->connect_data = NULL;
@@ -628,9 +603,10 @@ static void qq_connect_cb_continue(Purpl
 	qd->fd = source;
 	qd->logged_in = FALSE;
 	qd->channel = 1;
-	qd->uid = strtol(purple_account_get_username(account), NULL, 10);
+	qd->uid = strtol(purple_account_get_username(purple_connection_get_account(gc)), NULL, 10);
 
 	/* now generate md5 processed passwd */
+	passwd = purple_account_get_password(purple_connection_get_account(gc));
 
 	/* use twice-md5 of user password as session key since QQ 2003iii */
 	qq_get_md5(qd->password_twice_md5, sizeof(qd->password_twice_md5),
============================================================
--- libpurple/protocols/sametime/sametime.c	d439635129e338429aa7206dba80afca5aff7a96
+++ libpurple/protocols/sametime/sametime.c	f57a2836e3579dc767727265d04760f695730200
@@ -42,7 +42,6 @@
 #include "debug.h"
 #include "ft.h"
 #include "imgstore.h"
-#include "keyring.h"
 #include "mime.h"
 #include "notify.h"
 #include "plugin.h"
@@ -312,8 +311,7 @@ struct named_id {
 
 
 /* connection functions */
-static void mw_prpl_login_continue(PurpleAccount * account,
-	char * pass, GError * error, gpointer data);
+
 static void connect_cb(gpointer data, gint source, const gchar *error_message);
 
 
@@ -3707,20 +3705,11 @@ static void prompt_host(PurpleConnection
 }
 
 
-static void mw_prpl_login(PurpleAccount *account)
-{
-	purple_account_get_password_async(account, mw_prpl_login_continue, NULL);
-}
-
-static void mw_prpl_login_continue(PurpleAccount * account,
-				   char * pass,
-				   GError * error,
-				   gpointer data)
-{
+static void mw_prpl_login(PurpleAccount *account) {
   PurpleConnection *gc;
   struct mwPurplePluginData *pd;
 
-  char *user, *host;
+  char *user, *pass, *host;
   guint port;
 
   gc = purple_account_get_connection(account);
@@ -3730,6 +3719,7 @@ static void mw_prpl_login_continue(Purpl
   gc->flags |= PURPLE_CONNECTION_NO_IMAGES;
 
   user = g_strdup(purple_account_get_username(account));
+  pass = g_strdup(purple_account_get_password(account));
 
   host = strrchr(user, ':');
   if(host) {
============================================================
--- libpurple/protocols/silc/silc.c	4e17c145d01b9dfac317b251a3c1eaa4c864552f
+++ libpurple/protocols/silc/silc.c	ec27b9d2305549d9aa39f8c4c54124177e80a088
@@ -511,25 +511,11 @@ static void silcpurple_no_password_cb(Pu
 	silc_free(sg);
 }
 
-static void silcpurple_running_continue(PurpleAccount * account, 
-	char * password, GError * error, gpointer context);
-
 static void silcpurple_running(SilcClient client, void *context)
 {
 	SilcPurple sg = context;
 	PurpleConnection *gc = sg->gc;
-
 	PurpleAccount *account = purple_connection_get_account(gc);
-	purple_account_get_password_async(account, silcpurple_running_continue, context);
-}
-
-static void silcpurple_running_continue(PurpleAccount * account,
-					char * password,
-					GError * error,
-					gpointer context)
-{
-	SilcPurple sg = context;
-	PurpleConnection *gc = sg->gc;
 	char pkd[256], prd[256];
 
 
@@ -543,7 +529,7 @@ static void silcpurple_running_continue(
 				(char *)purple_account_get_string(account, "private-key", prd),
 				(gc->password == NULL) ? "" : gc->password,
 				&sg->public_key, &sg->private_key)) {
-		if (!password) {
+		if (!purple_account_get_password(account)) {
 			purple_account_request_password(account, G_CALLBACK(silcpurple_got_password_cb),
 											G_CALLBACK(silcpurple_no_password_cb), gc);
 			return;
============================================================
--- pidgin/gtkaccount.c	8c71060d98085bec815d7e9478c4186abdfcf2ac
+++ pidgin/gtkaccount.c	f268cd6fe62a189495bb33bd53e76882072925b0
@@ -138,6 +138,7 @@ typedef struct
 
 } AccountPrefsDialog;
 
+
 static AccountsWindow *accounts_window = NULL;
 static GHashTable *account_pref_wins;
 
@@ -148,6 +149,7 @@ static void set_account(GtkListStore *st
 /**************************************************************************
  * Add/Modify Account dialog
  **************************************************************************/
+static void pidgin_account_dialog_show_continue(PurpleAccount * account, char * password, GError * error, gpointer data);
 static void add_login_options(AccountPrefsDialog *dialog, GtkWidget *parent);
 static void add_user_options(AccountPrefsDialog *dialog, GtkWidget *parent);
 static void add_protocol_options(AccountPrefsDialog *dialog,
@@ -561,9 +563,9 @@ add_login_options(AccountPrefsDialog *di
 
 	/* Set the fields. */
 	if (dialog->account != NULL) {
-		if (purple_account_get_password(dialog->account))
-			gtk_entry_set_text(GTK_ENTRY(dialog->password_entry),
-							   purple_account_get_password(dialog->account));
+		if (purple_account_get_password(dialog->account) != NULL)
+			gtk_entry_set_text(GTK_ENTRY(dialog->password_entry), 
+				purple_account_get_password(dialog->account));
 
 		gtk_toggle_button_set_active(
 				GTK_TOGGLE_BUTTON(dialog->remember_pass_check),
@@ -1457,10 +1459,23 @@ static const GtkTargetEntry dnd_targets[
 	{"STRING", 0, 2}
 };
 
+
 void
 pidgin_account_dialog_show(PidginAccountDialogType type,
-							 PurpleAccount *account)
+			   PurpleAccount *account)
 {
+	/* this is to make sure the password will be cached */
+	purple_account_get_password_async(account,
+		pidgin_account_dialog_show_continue, (void*)type);
+}
+
+static void
+pidgin_account_dialog_show_continue(PurpleAccount * account,
+			   char * password,
+			   GError * error,
+			   gpointer data)
+{
+	PidginAccountDialogType type = (PidginAccountDialogType)data;
 	AccountPrefsDialog *dialog;
 	GtkWidget *win;
 	GtkWidget *main_vbox;
@@ -1524,6 +1539,7 @@ pidgin_account_dialog_show(PidginAccount
 
 	/* Setup the top frames. */
 	add_login_options(dialog, vbox);
+
 	add_user_options(dialog, vbox);
 
 	button = gtk_check_button_new_with_mnemonic(
@@ -2069,7 +2085,7 @@ populate_accounts_list(AccountsWindow *d
 	if (global_buddyicon != NULL)
 		g_object_unref(G_OBJECT(global_buddyicon));
 
-	return ret;
+	return ret; 
 }
 
 #if !GTK_CHECK_VERSION(2,2,0)


More information about the Commits mailing list