changeset 30778:acc66653b4ff

propagate from branch 'im.pidgin.cpw.qulogic.msnp16' (head 49bf2f5880edfe6f07decbf14418f2032ba59ad0) to branch 'im.pidgin.soc.2010.msn-tlc' (head b14a4e8fae0513bf8f5883c852a30bb8c3bcfc55)
author masca@cpw.pidgin.im
date Wed, 02 Jun 2010 20:51:24 +0000
parents 562498203fe8 (current diff) 712c8ddcf5ed (diff)
children 23b7b1b817c8
files libpurple/protocols/msn/directconn.c libpurple/protocols/msn/notification.c libpurple/protocols/msn/slp.c libpurple/protocols/msn/slplink.c
diffstat 40 files changed, 333 insertions(+), 164 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/msn/cmdproc.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/cmdproc.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,8 +21,12 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "debug.h"
+
 #include "cmdproc.h"
+#include "error.h"
 
 MsnCmdProc *
 msn_cmdproc_new(MsnSession *session)
--- a/libpurple/protocols/msn/cmdproc.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/cmdproc.h	Wed Jun 02 20:51:24 2010 +0000
@@ -27,7 +27,6 @@
 typedef struct _MsnCmdProc MsnCmdProc;
 
 #include "command.h"
-#include "error.h"
 #include "history.h"
 #include "servconn.h"
 #include "session.h"
--- a/libpurple/protocols/msn/command.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/command.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,7 +21,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+#include "internal.h"
+
 #include "command.h"
 
 static gboolean
--- a/libpurple/protocols/msn/contact.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/contact.c	Wed Jun 02 20:51:24 2010 +0000
@@ -24,12 +24,16 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA
  */
 
-#include "msn.h"
+#include "internal.h"
+#include "debug.h"
+
 #include "contact.h"
 #include "xmlnode.h"
 #include "group.h"
+#include "msnutils.h"
 #include "soap.h"
 #include "nexus.h"
+#include "user.h"
 
 const char *MsnSoapPartnerScenarioText[] =
 {
@@ -1167,7 +1171,7 @@
 		msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL);
 		msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL);
 
-		if (msn_userlist_user_is_in_list(user, MSN_LIST_PL)) {
+		if (msn_user_is_in_list(user, MSN_LIST_PL)) {
 			msn_del_contact_from_list(state->session, NULL, state->who, MSN_LIST_PL);
 			return;
 		}
--- a/libpurple/protocols/msn/directconn.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/directconn.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,6 +21,11 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+
+#include "internal.h"
+#include "cipher.h"
+#include "debug.h"
+
 #include "msn.h"
 #include "directconn.h"
 
--- a/libpurple/protocols/msn/error.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/error.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,7 +21,12 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "debug.h"
+/* Masca: can we get rid of the sync issue dialog? */
+#include "request.h"
+
 #include "error.h"
 
 typedef struct
--- a/libpurple/protocols/msn/group.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/group.h	Wed Jun 02 20:51:24 2010 +0000
@@ -26,7 +26,7 @@
 
 typedef struct _MsnGroup  MsnGroup;
 
-#include <stdio.h>
+#include "internal.h"
 
 #include "session.h"
 #include "user.h"
--- a/libpurple/protocols/msn/history.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/history.h	Wed Jun 02 20:51:24 2010 +0000
@@ -24,6 +24,8 @@
 #ifndef MSN_HISTORY_H
 #define MSN_HISTORY_H
 
+#include "internal.h"
+
 typedef struct _MsnHistory MsnHistory;
 
 #include "transaction.h"
--- a/libpurple/protocols/msn/httpconn.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/httpconn.h	Wed Jun 02 20:51:24 2010 +0000
@@ -28,6 +28,7 @@
 
 #include "circbuffer.h"
 #include "servconn.h"
+#include "session.h"
 
 /**
  * An HTTP Connection.
--- a/libpurple/protocols/msn/msg.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/msg.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,6 +21,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+
+#include "internal.h"
+#include "debug.h"
+
 #include "msn.h"
 #include "msg.h"
 #include "msnutils.h"
@@ -883,8 +887,9 @@
 				swboard->flag |= MSN_SB_FLAG_IM;
 			}
 		}
-		else
+		else if (!g_str_equal(passport, purple_account_get_username(gc->account)))
 		{
+			/* Don't im ourselves ... */
 			serv_got_im(gc, passport, body_final, 0, time(NULL));
 			if (swboard->conv == NULL)
 			{
--- a/libpurple/protocols/msn/msg.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/msg.h	Wed Jun 02 20:51:24 2010 +0000
@@ -67,6 +67,23 @@
 #define MSG_OIM_BODY_DEM	"\n\n"
 #define MSG_OIM_LINE_DEM	"\n"
 
+typedef enum
+{
+	SLP_HF_NO_FLAG         = 0x0,        /**< No flags specified */
+	SLP_HF_OUT_OF_ORDER    = 0x1,        /**< Chunk out-of-order */
+	SLP_HF_ACK             = 0x2,        /**< Acknowledgement */
+	SLP_HF_PENDING_INVITE  = 0x4,        /**< There is a pending invite */
+	SLP_HF_BINARY_ERROR    = 0x8,        /**< Error on the binary level */
+	SLP_HF_MSN_OBJ_DATA    = 0x20,       /**< MsnObject data */
+	SLP_HF_WML2009_COMP    = 0x1000000,  /**< Compatibility with WLM 2009 */
+	SLP_HF_FILE_DATA       = 0x1000030   /**< File transfer data */
+} SlpHeaderFlag;
+/* Info From:
+ * http://msnpiki.msnfanatic.com/index.php/MSNC:P2Pv1_Headers#Flags
+ * http://trac.kmess.org/changeset/ba04d0c825769d23370511031c47f6be75fe9b86
+ * #7180
+ */
+
 typedef struct
 {
 	guint32 session_id;
--- a/libpurple/protocols/msn/msn.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/msn.c	Wed Jun 02 20:51:24 2010 +0000
@@ -23,7 +23,11 @@
  */
 #define PHOTO_SUPPORT 1
 
-#include "msn.h"
+#include "internal.h"
+
+#include "debug.h"
+#include "request.h"
+
 #include "accountopt.h"
 #include "contact.h"
 #include "msg.h"
@@ -40,6 +44,7 @@
 #include "msnutils.h"
 #include "version.h"
 
+#include "error.h"
 #include "msg.h"
 #include "switchboard.h"
 #include "notification.h"
@@ -115,29 +120,6 @@
 	return buf;
 }
 
-gboolean
-msn_email_is_valid(const char *passport)
-{
-	if (purple_email_is_valid(passport)) {
-		/* Special characters aren't allowed in domains, so only go to '@' */
-		while (*passport != '@') {
-			if (*passport == '/')
-				return FALSE;
-			else if (*passport == '?')
-				return FALSE;
-			else if (*passport == '=')
-				return FALSE;
-			/* MSN also doesn't like colons, but that's checked already */
-
-			passport++;
-		}
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
 static gboolean
 msn_send_attention(PurpleConnection *gc, const char *username, guint type)
 {
@@ -1700,7 +1682,7 @@
 		MsnUser *user2 = msn_userlist_find_user(userlist, who);
 		if (user2 != NULL) {
 			/* User already in userlist, so just update it. */
-			msn_user_destroy(user);
+			msn_user_unref(user);
 			user = user2;
 		} else {
 			msn_userlist_add_user(userlist, user);
@@ -1720,7 +1702,7 @@
 
 		/* Remove from local list */
 		purple_blist_remove_buddy(buddy);
-		msn_user_destroy(user);
+		msn_user_unref(user);
 	}
 	g_free(group);
 }
--- a/libpurple/protocols/msn/msn.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/msn.h	Wed Jun 02 20:51:24 2010 +0000
@@ -26,16 +26,6 @@
 
 typedef enum
 {
-	MSN_LIST_FL_OP = 0x01,
-	MSN_LIST_AL_OP = 0x02,
-	MSN_LIST_BL_OP = 0x04,
-	MSN_LIST_RL_OP = 0x08,
-	MSN_LIST_PL_OP = 0x10
-} MsnListOp;
-#define MSN_LIST_OP_MASK	0x07
-
-typedef enum
-{
 	MSN_CLIENT_CAP_WIN_MOBILE = 0x0000001,
 	MSN_CLIENT_CAP_INK_GIF    = 0x0000004,
 	MSN_CLIENT_CAP_INK_ISF    = 0x0000008,
@@ -83,23 +73,7 @@
 
 #include "internal.h"
 
-#include "account.h"
-#include "accountopt.h"
-#include "blist.h"
-#include "connection.h"
-#include "conversation.h"
-#include "debug.h"
-#include "cipher.h"
-#include "notify.h"
-#include "privacy.h"
-#include "proxy.h"
-#include "prpl.h"
-#include "request.h"
-#include "servconn.h"
-#include "sslconn.h"
-#include "util.h"
-
-#include "ft.h"
+#include "session.h"
 
 #include "msg.h"
 
@@ -142,7 +116,6 @@
 	((MSN_CLIENT_ID_VERSION    << 24) | \
 	 (MSN_CLIENT_ID_CAPABILITIES))
 
-gboolean msn_email_is_valid(const char *passport);
 void
 msn_set_public_alias(PurpleConnection *gc, const char *alias,
                      PurpleSetPublicAliasSuccessCallback success_cb,
--- a/libpurple/protocols/msn/msnutils.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/msnutils.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,6 +21,9 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+
+#include "internal.h"
+
 #include "msn.h"
 #include "msnutils.h"
 
@@ -474,6 +477,29 @@
 	*ret_port = port;
 }
 
+gboolean
+msn_email_is_valid(const char *passport)
+{
+	if (purple_email_is_valid(passport)) {
+		/* Special characters aren't allowed in domains, so only go to '@' */
+		while (*passport != '@') {
+			if (*passport == '/')
+				return FALSE;
+			else if (*passport == '?')
+				return FALSE;
+			else if (*passport == '=')
+				return FALSE;
+			/* MSN also doesn't like colons, but that's checked already */
+
+			passport++;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
 /***************************************************************************
  * MSN Challenge Computing Function
  ***************************************************************************/
--- a/libpurple/protocols/msn/msnutils.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/msnutils.h	Wed Jun 02 20:51:24 2010 +0000
@@ -64,6 +64,15 @@
 void msn_parse_socket(const char *str, char **ret_host, int *ret_port);
 
 /**
+ * Verify if the email is a vaild passport.
+ *
+ * @param passport 	The email
+ *
+ * @return True if it is a valid passport, else FALSE
+ */
+gboolean msn_email_is_valid(const char *passport);
+
+/**
  * Handle MSN Challenge Computation
  * This algorithm references
  * http://imfreedom.org/wiki/index.php/MSN:NS/Challenges
--- a/libpurple/protocols/msn/nexus.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/nexus.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,7 +21,11 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "cipher.h"
+#include "debug.h"
+
 #include "soap.h"
 #include "nexus.h"
 #include "notification.h"
--- a/libpurple/protocols/msn/nexus.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/nexus.h	Wed Jun 02 20:51:24 2010 +0000
@@ -24,6 +24,8 @@
 #ifndef MSN_NEXUS_H
 #define MSN_NEXUS_H
 
+#include "internal.h"
+
 typedef struct _MsnNexus MsnNexus;
 typedef struct _MsnTicketToken MsnTicketToken;
 typedef struct _MsnUsrKey MsnUsrKey;
--- a/libpurple/protocols/msn/notification.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/notification.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,17 +21,19 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "cipher.h"
 #include "core.h"
+#include "debug.h"
+
 #include "notification.h"
+
 #include "contact.h"
-#include "state.h"
 #include "error.h"
 #include "msnutils.h"
-#include "page.h"
-
+#include "state.h"
 #include "userlist.h"
-#include "slplink.h"
 
 static MsnTable *cbs_table;
 
--- a/libpurple/protocols/msn/notification.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/notification.h	Wed Jun 02 20:51:24 2010 +0000
@@ -45,6 +45,7 @@
 #include "servconn.h"
 #include "state.h"
 #include "user.h"
+#include "userlist.h"
 
 struct _MsnNotification
 {
--- a/libpurple/protocols/msn/oim.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/oim.c	Wed Jun 02 20:51:24 2010 +0000
@@ -23,7 +23,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "debug.h"
+
 #include "soap.h"
 #include "oim.h"
 #include "msnutils.h"
--- a/libpurple/protocols/msn/servconn.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/servconn.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,7 +21,9 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+#include "internal.h"
+#include "debug.h"
+
 #include "servconn.h"
 #include "error.h"
 
--- a/libpurple/protocols/msn/servconn.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/servconn.h	Wed Jun 02 20:51:24 2010 +0000
@@ -46,6 +46,7 @@
 	MSN_SERVCONN_SB
 } MsnServConnType;
 
+#include "internal.h"
 #include "proxy.h"
 
 #include "cmdproc.h"
--- a/libpurple/protocols/msn/session.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/session.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,8 +21,11 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+
+#include "internal.h"
+#include "debug.h"
+
 #include "error.h"
-#include "msn.h"
 #include "msnutils.h"
 #include "session.h"
 #include "notification.h"
@@ -81,7 +84,7 @@
 		msn_nexus_destroy(session->nexus);
 
 	if (session->user != NULL)
-		msn_user_destroy(session->user);
+		msn_user_unref(session->user);
 
 	if (session->notification != NULL)
 		msn_notification_destroy(session->notification);
--- a/libpurple/protocols/msn/session.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/session.h	Wed Jun 02 20:51:24 2010 +0000
@@ -59,13 +59,10 @@
 
 #define MSN_LOGIN_STEPS MSN_LOGIN_STEP_END
 
-#include "group.h"
-#include "httpconn.h"
 #include "nexus.h"
 #include "notification.h"
 #include "oim.h"
 #include "slpcall.h"
-#include "sslconn.h"
 #include "switchboard.h"
 #include "user.h"
 #include "userlist.h"
--- a/libpurple/protocols/msn/slp.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/slp.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,7 +21,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "debug.h"
+
 #include "slp.h"
 #include "slpcall.h"
 #include "slpmsg.h"
@@ -515,7 +518,7 @@
 			/* DATA */
 			slpmsg = msn_slpmsg_new(slplink);
 			slpmsg->slpcall = slpcall;
-			slpmsg->flags = 0x20;
+			slpmsg->flags = SLP_HF_MSN_OBJ_DATA;
 			slpmsg->info = "SLP DATA";
 			msn_slpmsg_set_image(slpmsg, img);
 			msn_slplink_queue_slpmsg(slplink, slpmsg);
--- a/libpurple/protocols/msn/slp.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/slp.h	Wed Jun 02 20:51:24 2010 +0000
@@ -26,7 +26,6 @@
 
 #include "internal.h"
 
-#include "ft.h"
 #include "session.h"
 #include "slpcall.h"
 
--- a/libpurple/protocols/msn/slpcall.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,7 +21,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "debug.h"
+
 #include "msnutils.h"
 #include "slpcall.h"
 
@@ -201,7 +204,7 @@
 	body = slpmsg->buffer;
 	body_len = slpmsg->offset;
 
-	if (slpmsg->flags == 0x0 || slpmsg->flags == 0x1000000)
+	if (slpmsg->flags == SLP_HF_NO_FLAG || slpmsg->flags == SLP_HF_WML2009_COMP)
 	{
 		char *body_str;
 
@@ -262,9 +265,9 @@
 		}
 		g_free(body_str);
 	}
-	else if (slpmsg->flags == 0x20 ||
-	         slpmsg->flags == 0x1000020 ||
-	         slpmsg->flags == 0x1000030)
+	else if (slpmsg->flags == SLP_HF_MSN_OBJ_DATA ||
+	         slpmsg->flags == SLP_HF_WML2009_COMP & SLP_HF_MSN_OBJ_DATA ||
+	         slpmsg->flags == SLP_HF_FILE_DATA)
 	{
 		slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id);
 
@@ -290,7 +293,7 @@
 			msn_slpcall_session_init(slpcall);
 	}
 #endif
-	else if (slpmsg->flags == 0x2)
+	else if (slpmsg->flags == SLP_HF_ACK)
 	{
 		/* Acknowledgement of previous message. Don't do anything currently. */
 	}
--- a/libpurple/protocols/msn/slpcall.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/slpcall.h	Wed Jun 02 20:51:24 2010 +0000
@@ -34,8 +34,6 @@
 
 #include "internal.h"
 
-#include "ft.h"
-
 #include "slplink.h"
 
 /* The official client seems to timeout slp calls after 5 minutes */
--- a/libpurple/protocols/msn/slplink.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/slplink.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,6 +21,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+
+#include "internal.h"
+#include "debug.h"
+
 #include "msn.h"
 #include "slplink.h"
 
@@ -294,7 +298,7 @@
 	 * reusing the same one all the time. */
 	msg = slpmsg->msg;
 
-	real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size;
+	real_size = (slpmsg->flags == SLP_HF_ACK) ? 0 : slpmsg->size;
 
 	if (slpmsg->offset < real_size)
 	{
@@ -329,8 +333,9 @@
 		g_list_append(slpmsg->msgs, msn_message_ref(msg));
 	msn_slplink_send_msg(slplink, msg);
 
-	if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 ||
-	     slpmsg->flags == 0x1000030) &&
+	if ((slpmsg->flags == SLP_HF_MSN_OBJ_DATA || 
+	     slpmsg->flags == (SLP_HF_WML2009_COMP & SLP_HF_MSN_OBJ_DATA) ||
+	     slpmsg->flags == SLP_HF_FILE_DATA) &&
 		(slpmsg->slpcall != NULL))
 	{
 		slpmsg->slpcall->progress = TRUE;
@@ -354,7 +359,7 @@
 
 	slpmsg = data;
 
-	real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size;
+	real_size = (slpmsg->flags == SLP_HF_ACK) ? 0 : slpmsg->size;
 
 	slpmsg->offset += msg->msnslp_header.length;
 
@@ -374,8 +379,9 @@
 	else
 	{
 		/* The whole message has been sent */
-		if (slpmsg->flags == 0x20 ||
-		    slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030)
+		if (slpmsg->flags == SLP_HF_MSN_OBJ_DATA ||
+	        slpmsg->flags == (SLP_HF_WML2009_COMP & SLP_HF_MSN_OBJ_DATA) ||
+	        slpmsg->flags == SLP_HF_FILE_DATA) 
 		{
 			if (slpmsg->slpcall != NULL)
 			{
@@ -411,20 +417,21 @@
 
 	slpmsg->msg = msg = msn_message_new_msnslp();
 
-	if (slpmsg->flags == 0x0)
+	if (slpmsg->flags == SLP_HF_NO_FLAG)
 	{
 		msg->msnslp_header.session_id = slpmsg->session_id;
 		msg->msnslp_header.ack_id = rand() % 0xFFFFFF00;
 	}
-	else if (slpmsg->flags == 0x2)
+	else if (slpmsg->flags == SLP_HF_ACK)
 	{
 		msg->msnslp_header.session_id = slpmsg->session_id;
 		msg->msnslp_header.ack_id = slpmsg->ack_id;
 		msg->msnslp_header.ack_size = slpmsg->ack_size;
 		msg->msnslp_header.ack_sub_id = slpmsg->ack_sub_id;
 	}
-	else if (slpmsg->flags == 0x20 ||
-	         slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030)
+	else if (slpmsg->flags == SLP_HF_MSN_OBJ_DATA ||
+	         slpmsg->flags == (SLP_HF_WML2009_COMP & SLP_HF_MSN_OBJ_DATA) ||
+	         slpmsg->flags == SLP_HF_FILE_DATA)
 	{
 		MsnSlpCall *slpcall;
 		slpcall = slpmsg->slpcall;
@@ -497,7 +504,7 @@
 
 	slpmsg->session_id = header->session_id;
 	slpmsg->size       = header->total_size;
-	slpmsg->flags      = 0x02;
+	slpmsg->flags      = SLP_HF_ACK;
 	slpmsg->ack_id     = header->id;
 	slpmsg->ack_sub_id = header->ack_id;
 	slpmsg->ack_size   = header->total_size;
@@ -535,7 +542,7 @@
 
 	slpmsg = msn_slpmsg_new(slpcall->slplink);
 	slpmsg->slpcall = slpcall;
-	slpmsg->flags = 0x1000030;
+	slpmsg->flags = SLP_HF_FILE_DATA;
 	slpmsg->info = "SLP FILE";
 	slpmsg->size = purple_xfer_get_size(xfer);
 
@@ -588,8 +595,9 @@
 			slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id);
 			if (slpmsg->slpcall != NULL)
 			{
-				if (slpmsg->flags == 0x20 ||
-				    slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030)
+				if (slpmsg->flags == SLP_HF_MSN_OBJ_DATA ||
+					slpmsg->flags == (SLP_HF_WML2009_COMP & SLP_HF_MSN_OBJ_DATA) ||
+					slpmsg->flags == SLP_HF_FILE_DATA)
 				{
 					PurpleXfer *xfer = slpmsg->slpcall->xfer;
 					if (xfer != NULL)
@@ -653,8 +661,9 @@
 		}
 	}
 
-	if ((slpmsg->flags == 0x20 ||
-	     slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) &&
+	if ((slpmsg->flags == SLP_HF_MSN_OBJ_DATA ||
+		slpmsg->flags == (SLP_HF_WML2009_COMP & SLP_HF_MSN_OBJ_DATA) ||
+		slpmsg->flags == SLP_HF_FILE_DATA) &&
 		(slpmsg->slpcall != NULL))
 	{
 		slpmsg->slpcall->progress = TRUE;
@@ -695,9 +704,10 @@
 				msn_directconn_send_handshake(directconn);
 #endif
 		}
-		else if (slpmsg->flags == 0x00 || slpmsg->flags == 0x1000000 ||
-		         slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 ||
-		         slpmsg->flags == 0x1000030)
+		else if (slpmsg->flags == SLP_HF_NO_FLAG || slpmsg->flags == SLP_HF_WML2009_COMP ||
+			slpmsg->flags == SLP_HF_MSN_OBJ_DATA ||
+			slpmsg->flags == (SLP_HF_WML2009_COMP & SLP_HF_MSN_OBJ_DATA) ||
+			slpmsg->flags == SLP_HF_FILE_DATA)
 		{
 			/* Release all the messages and send the ACK */
 
--- a/libpurple/protocols/msn/slplink.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/slplink.h	Wed Jun 02 20:51:24 2010 +0000
@@ -26,8 +26,6 @@
 
 typedef struct _MsnSlpLink MsnSlpLink;
 
-#include "ft.h"
-
 #include "directconn.h"
 #include "session.h"
 #include "slpcall.h"
--- a/libpurple/protocols/msn/slpmsg.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/slpmsg.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,7 +21,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "debug.h"
+
 #include "slpmsg.h"
 #include "slplink.h"
 
--- a/libpurple/protocols/msn/state.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/state.c	Wed Jun 02 20:51:24 2010 +0000
@@ -23,10 +23,10 @@
  */
 
 #include "internal.h"
+#include "debug.h"
 
 #include "core.h"
 
-#include "msn.h"
 #include "notification.h"
 #include "state.h"
 
--- a/libpurple/protocols/msn/switchboard.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/switchboard.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,13 +21,15 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
-#include "prefs.h"
+
+#include "internal.h"
+#include "debug.h"
+
+#include "msnutils.h"
 #include "switchboard.h"
-#include "notification.h"
-#include "msnutils.h"
-
-#include "error.h"
+#include "slplink.h"
+#include "user.h"
+#include "userlist.h"
 
 static MsnTable *cbs_table;
 
@@ -123,7 +125,7 @@
 	g_free(swboard->session_id);
 
 	for (; swboard->users; swboard->users = g_list_delete_link(swboard->users, swboard->users))
-		g_free(swboard->users->data);
+		msn_user_unref(swboard->users->data);
 
 	session = swboard->session;
 	session->switches = g_list_remove(session->switches, swboard);
@@ -226,11 +228,23 @@
 	msn_message_destroy(msg);
 }
 
+static int
+user_passport_cmp(MsnUser *user, const char *passport)
+{
+	const char *pass;
+
+	pass = msn_user_get_passport(user);
+
+	return strcmp(pass, passport);
+}
+
 static void
 msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
 {
 	MsnCmdProc *cmdproc;
 	PurpleAccount *account;
+	MsnUserList *userlist;
+	MsnUser *msnuser;
 	char *semicolon;
 	char *passport;
 
@@ -246,8 +260,11 @@
 	else
 		passport = g_strdup(user);
 
+	userlist = swboard->session->userlist;
+	msnuser = msn_userlist_find_user(userlist, passport);
+
 	/* Don't add multiple endpoints to the conversation. */
-	if (g_list_find_custom(swboard->users, passport, (GCompareFunc)strcmp)) {
+	if (g_list_find_custom(swboard->users, passport, (GCompareFunc)user_passport_cmp)) {
 		g_free(passport);
 		return;
 	}
@@ -257,8 +274,16 @@
 		g_free(passport);
 		return;
 	}
+	
+	if (!msnuser) {
+		purple_debug_info("msn","User %s is not on our list.\n", passport);
+		msnuser = msn_user_new(userlist, passport, NULL);
+	} else
+		msn_user_ref(msnuser);
 
-	swboard->users = g_list_prepend(swboard->users, passport);
+	g_free(passport);
+
+	swboard->users = g_list_prepend(swboard->users, msnuser);
 	swboard->current_users++;
 	swboard->empty = FALSE;
 
@@ -276,7 +301,7 @@
 	if ((swboard->conv != NULL) &&
 		(purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
 	{
-		purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), user, NULL,
+		purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), msnuser->passport, NULL,
 								PURPLE_CBFLAGS_NONE, TRUE);
 		msn_servconn_set_idle_timeout(swboard->servconn, 0);
 	}
@@ -304,8 +329,9 @@
 			for (l = swboard->users; l != NULL; l = l->next)
 			{
 				const char *tmp_user;
+				user = l->data;
 
-				tmp_user = l->data;
+				tmp_user = msnuser->passport;
 
 				purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),
 										tmp_user, NULL, PURPLE_CBFLAGS_NONE, TRUE);
@@ -322,7 +348,7 @@
 	else if (swboard->conv == NULL)
 	{
 		swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
-															user, account);
+															msnuser->passport, account);
 	}
 	else
 	{
--- a/libpurple/protocols/msn/switchboard.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/switchboard.h	Wed Jun 02 20:51:24 2010 +0000
@@ -50,12 +50,10 @@
 	MSN_SB_FLAG_FT = 0x02  /**< This switchboard is being used for file transfer. */
 } MsnSBFlag;
 
-#include "conversation.h"
-
+#include "cmdproc.h"
 #include "msg.h"
 #include "servconn.h"
-#include "slplink.h"
-#include "user.h"
+#include "session.h"
 
 /**
  * A switchboard.
--- a/libpurple/protocols/msn/transaction.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/transaction.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,6 +21,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+
+#include "internal.h"
+#include "debug.h"
+
 #include "msn.h"
 #include "transaction.h"
 
--- a/libpurple/protocols/msn/transaction.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/transaction.h	Wed Jun 02 20:51:24 2010 +0000
@@ -24,6 +24,8 @@
 #ifndef MSN_TRANSACTION_H
 #define MSN_TRANSACTION_H
 
+#include "internal.h"
+
 typedef struct _MsnTransaction MsnTransaction;
 
 #include "cmdproc.h"
--- a/libpurple/protocols/msn/user.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/user.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,7 +21,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "debug.h"
+
 #include "user.h"
 #include "slp.h"
 
@@ -46,15 +49,20 @@
 	msn_user_set_passport(user, passport);
 	msn_user_set_friendly_name(user, friendly_name);
 
-	return user;
+	return msn_user_ref(user);
 }
 
 /*destroy a user object*/
-void
+static void
 msn_user_destroy(MsnUser *user)
 {
 	g_return_if_fail(user != NULL);
 
+	if (user->refcount > 1) {
+		msn_user_unref(user);
+		return;
+	}
+
 	while (user->endpoints != NULL) {
 		free_user_endpoint(user->endpoints->data);
 		user->endpoints = g_slist_delete_link(user->endpoints, user->endpoints);
@@ -94,6 +102,27 @@
 	g_free(user);
 }
 
+MsnUser *
+msn_user_ref(MsnUser *user)
+{
+	g_return_val_if_fail(user != NULL, NULL);
+
+	user->refcount++;
+
+	return user;
+}
+
+void
+msn_user_unref(MsnUser *user)
+{
+	g_return_if_fail(user != NULL);
+
+	user->refcount--;
+
+	if(user->refcount == 0)
+		msn_user_destroy(user);
+}
+
 void
 msn_user_update(MsnUser *user)
 {
@@ -632,3 +661,29 @@
 
 	return (user->clientid & capability) && (user->extcaps & extcap);
 }
+
+/**************************************************************************
+ * Utility functions
+ **************************************************************************/
+
+gboolean
+msn_user_is_in_group(MsnUser *user, const char * group_id)
+{
+	if (user == NULL)
+		return FALSE;
+
+	if (group_id == NULL)
+		return FALSE;
+
+	return (g_list_find_custom(user->group_ids, group_id, (GCompareFunc)strcmp)) != NULL;
+}
+
+gboolean
+msn_user_is_in_list(MsnUser *user, MsnListId list_id)
+{
+	if (user == NULL)
+		return FALSE;
+
+	return (user->list_op & (1 << list_id));
+}
+
--- a/libpurple/protocols/msn/user.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/user.h	Wed Jun 02 20:51:24 2010 +0000
@@ -79,6 +79,8 @@
 {
 	MsnUserList *userlist;
 
+	guint8 refcount;        /**< The reference count of this object */
+
 	char *passport;         /**< The passport account.          */
 	char *friendly_name;    /**< The friendly name.             */
 
@@ -148,12 +150,20 @@
 					  const char *friendly_name);
 
 /**
- * Destroys a user structure.
+ * Increment the reference count.
+ *
+ * @param user 	The user.
  *
- * @param user The user to destroy.
+ * @return 		user.
  */
-void msn_user_destroy(MsnUser *user);
+MsnUser *msn_user_ref(MsnUser *user);
 
+/**
+ * Decrement the reference count.
+ *
+ * @param user 	The user
+ */
+void msn_user_unref(MsnUser *user);
 
 /**
  * Updates the user.
@@ -406,6 +416,30 @@
  */
 guint msn_user_get_extcaps(const MsnUser *user);
 
+/**************************************************************************
+ * Utility functions
+ **************************************************************************/
+
+
+/**
+ * Check if the user is part of the group.
+ *
+ * @param user 		The user we are asking group membership.
+ * @param group_id 	The group where the user may be in.
+ * 
+ * @return TRUE if user is part of the group. Otherwise, FALSE.
+ */
+gboolean msn_user_is_in_group(MsnUser *user, const char * group_id);
+
+/**
+ * Check if user is on list.
+ *
+ * @param user 		The user we are asking list membership.
+ * @param list_id 	The list where the user may be in.
+ *
+ * @return TRUE if the user is on the list, else FALSE.
+ */
+gboolean msn_user_is_in_list(MsnUser *user, MsnListId list_id);
 /**
  * Returns the network id for a user.
  *
--- a/libpurple/protocols/msn/userlist.c	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/userlist.c	Wed Jun 02 20:51:24 2010 +0000
@@ -21,7 +21,13 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+
+#include "internal.h"
+#include "debug.h"
+#include "request.h"
+
 #include "msn.h"
+#include "msnutils.h"
 #include "userlist.h"
 
 #include "contact.h"
@@ -107,31 +113,6 @@
 }
 
 /**************************************************************************
- * Utility functions
- **************************************************************************/
-
-gboolean
-msn_userlist_user_is_in_group(MsnUser *user, const char * group_id)
-{
-	if (user == NULL)
-		return FALSE;
-
-	if (group_id == NULL)
-		return FALSE;
-
-	return (g_list_find_custom(user->group_ids, group_id, (GCompareFunc)strcmp)) != NULL;
-}
-
-gboolean
-msn_userlist_user_is_in_list(MsnUser *user, MsnListId list_id)
-{
-	if (user == NULL)
-		return FALSE;
-
-	return (user->list_op & (1 << list_id));
-}
-
-/**************************************************************************
  * Server functions
  **************************************************************************/
 
@@ -235,7 +216,7 @@
 	/*destroy userlist*/
 	for (l = userlist->users; l != NULL; l = l->next)
 	{
-		msn_user_destroy(l->data);
+		msn_user_unref(l->data);
 	}
 	g_list_free(userlist->users);
 
@@ -503,7 +484,7 @@
 
 	g_return_if_fail(user != NULL);
 
-	if ( !msn_userlist_user_is_in_list(user, list_id)) {
+	if ( !msn_user_is_in_list(user, list_id)) {
 		list = lists[list_id];
 		purple_debug_info("msn", "User %s is not in list %s, not removing.\n", who, list);
 		return;
@@ -569,13 +550,13 @@
 
 	user = msn_userlist_find_add_user(userlist, who, who);
 
-	if ( msn_userlist_user_is_in_list(user, MSN_LIST_FL) ) {
+	if ( msn_user_is_in_list(user, MSN_LIST_FL) ) {
 
 		purple_debug_info("msn", "User %s already exists\n", who);
 
 		msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_BL);
 
-		if (msn_userlist_user_is_in_group(user, group_id)) {
+		if (msn_user_is_in_group(user, group_id)) {
 			purple_debug_info("msn", "User %s is already in group %s, returning\n", who, new_group_name);
 			msn_callback_state_free(state);
 			return;
@@ -604,7 +585,7 @@
 	user = msn_userlist_find_add_user(userlist, who, who);
 
 	/* First we're going to check if it's already there. */
-	if (msn_userlist_user_is_in_list(user, list_id))
+	if (msn_user_is_in_list(user, list_id))
 	{
 		list = lists[list_id];
 		purple_debug_info("msn", "User '%s' is already in list: %s\n", who, list);
--- a/libpurple/protocols/msn/userlist.h	Wed Jun 02 20:08:53 2010 +0000
+++ b/libpurple/protocols/msn/userlist.h	Wed Jun 02 20:51:24 2010 +0000
@@ -35,6 +35,16 @@
 	MSN_LIST_PL  /**< Pending list */
 } MsnListId;
 
+typedef enum
+{
+	MSN_LIST_FL_OP = 0x01,
+	MSN_LIST_AL_OP = 0x02,
+	MSN_LIST_BL_OP = 0x04,
+	MSN_LIST_RL_OP = 0x08,
+	MSN_LIST_PL_OP = 0x10
+} MsnListOp;
+#define MSN_LIST_OP_MASK	0x07
+
 #include "group.h"
 #include "msn.h"
 #include "user.h"
@@ -52,9 +62,6 @@
 
 };
 
-gboolean msn_userlist_user_is_in_group(MsnUser *user, const char * group_id);
-gboolean msn_userlist_user_is_in_list(MsnUser *user, MsnListId list_id);
-
 void msn_got_lst_user(MsnSession *session, MsnUser *user,
 					  MsnListOp list_op, GSList *group_ids);