changeset 20397:6ac7e33fdabf

propagate from branch 'im.pidgin.rlaager.merging.msnp13-and-sf-1621854-1-rlaager-whitespace' (head 5083cfbc09503360bacf3ff0ebf528700770e6af) to branch 'im.pidgin.rlaager.merging.msnp13-and-sf-1621854-4-rlaager-whitespace' (head 4d82c29e56bd33cd6f94302e343dfeb5d68ab3eb)
author Richard Laager <rlaager@wiktel.com>
date Sun, 15 Apr 2007 03:04:05 +0000
parents 40a04930b233 (diff) 9755b2f7bb0f (current diff)
children 61d6a3dfbb3c
files libgaim/protocols/msn/msn.c libgaim/protocols/msn/servconn.c libgaim/protocols/msn/userlist.c
diffstat 22 files changed, 212 insertions(+), 1300 deletions(-) [+]
line wrap: on
line diff
--- a/libgaim/protocols/msn/Makefile.am	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/Makefile.am	Sun Apr 15 03:04:05 2007 +0000
@@ -66,8 +66,8 @@
 	user.h \
 	userlist.c \
 	userlist.h \
-	msn-utils.c \
-	msn-utils.h
+	msnutils.c \
+	msnutils.h
 
 AM_CFLAGS = $(st)
 
--- a/libgaim/protocols/msn/Makefile.mingw	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/Makefile.mingw	Sun Apr 15 03:04:05 2007 +0000
@@ -68,7 +68,7 @@
 			transaction.c \
 			user.c \
 			userlist.c \
-			msn-utils.c
+			msnutils.c
 
 OBJECTS = $(C_SRC:%.c=%.o)
 
--- a/libgaim/protocols/msn/contact.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/contact.c	Sun Apr 15 03:04:05 2007 +0000
@@ -33,8 +33,6 @@
 /*define This to debug the Contact Server*/
 #undef  MSN_CONTACT_SOAP_DEBUG
 
-void msn_contact_connect_init(MsnSoapConn *soapconn);
-
 /*new a contact*/
 MsnContact *
 msn_contact_new(MsnSession *session)
@@ -144,6 +142,17 @@
 	body = xmlnode_get_child(node,"Body");
 	gaim_debug_misc("MSNCL","body{%p},name:%s\n",body,body->name);
 	response = xmlnode_get_child(body,"FindMembershipResponse");
+
+	if (response == NULL) {
+		/* we may get a response if our cache data is too old:
+		 *
+		 * <faultstring>Need to do full sync. Can't sync deltas Client
+		 * has too old a copy for us to do a delta sync</faultstring>
+		 */
+		msn_get_contact_list(contact, NULL);
+		return;
+	}
+
 	gaim_debug_misc("MSNCL","response{%p},name:%s\n",response,response->name);
 	result =xmlnode_get_child(response,"FindMembershipResult");
 	if(result == NULL){
@@ -250,7 +259,7 @@
 
 /*SOAP  get contact list*/
 void
-msn_get_contact_list(MsnContact * contact,char * update_time)
+msn_get_contact_list(MsnContact * contact, const char *update_time)
 {
 	MsnSoapReq *soap_request;
 	char *body = NULL;
@@ -263,7 +272,7 @@
 	}else{
 		update_str = g_strdup("");
 	}
-	body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE,update_str);
+	body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, update_str);
 	soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
 					MSN_GET_CONTACT_POST_URL,MSN_GET_CONTACT_SOAP_ACTION,
 					body,
@@ -274,7 +283,7 @@
 	g_free(body);
 }
 
-static void
+static gboolean
 msn_parse_addressbook(MsnContact * contact)
 {
 	MsnSession * session;
@@ -290,17 +299,22 @@
 
 	if(node == NULL){
 		gaim_debug_misc("xml","parse from str err!\n");
-		return;
+		return FALSE;
 	}
 	gaim_debug_misc("xml","node{%p},name:%s,child:%s,last:%s\n",node,node->name,node->child->name,node->lastchild->name);
 	body = xmlnode_get_child(node,"Body");
 	gaim_debug_misc("xml","body{%p},name:%s\n",body,body->name);
 	response = xmlnode_get_child(body,"ABFindAllResponse");
+
+	if (response == NULL) {
+		return FALSE;
+	}
+
 	gaim_debug_misc("xml","response{%p},name:%s\n",response,response->name);
 	result =xmlnode_get_child(response,"ABFindAllResult");
 	if(result == NULL){
 		gaim_debug_misc("MSNAB","receive no address book update\n");
-		return;
+		return TRUE;
 	}
 	gaim_debug_misc("xml","result{%p},name:%s\n",result,result->name);
 
@@ -378,7 +392,7 @@
 		/*setup the Display Name*/
 		if (!strcmp(type, "Me")){
 			char *friendly;
-			friendly = xmlnode_get_data(xmlnode_get_child(contactInfo,"displayName"));
+			friendly = xmlnode_get_data(xmlnode_get_child(contactInfo, "displayName"));
 			gaim_connection_set_display_name(session->account->gc, gaim_url_decode(friendly));
 			g_free(friendly);
 		}
@@ -480,6 +494,7 @@
 
 	xmlnode_free(node);
 	msn_soap_free_read_buf(contact->soapconn);
+	return TRUE;
 }
 
 static void
@@ -495,11 +510,13 @@
 	g_return_if_fail(session != NULL);
 
 //	gaim_debug_misc("msn", "soap contact server Reply: {%s}\n", soapconn->read_buf);
-	msn_parse_addressbook(contact);
-
-	msn_notification_dump_contact(session);
-	msn_set_psm(session);
-	msn_session_finish_login(session);
+	if (msn_parse_addressbook(contact)) {
+		msn_notification_dump_contact(session);
+		msn_set_psm(session);
+		msn_session_finish_login(session);
+	} else {
+		msn_get_address_book(contact, NULL, NULL);
+	}
 
 	/*free the read buffer*/
 	msn_soap_free_read_buf(soapconn);
--- a/libgaim/protocols/msn/contact.h	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/contact.h	Sun Apr 15 03:04:05 2007 +0000
@@ -197,6 +197,7 @@
 #define MSN_GROUP_DEL_SOAP_ACTION	"http://www.msn.com/webservices/AddressBook/ABGroupDelete"
 #define MSN_GROUP_DEL_TEMPLATE	"<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"><soap:Header><ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\"><ApplicationId>09607671-1C32-421F-A6A6-CBFAA51AB5F4</ApplicationId><IsMigration>false</IsMigration><PartnerScenario>Timer</PartnerScenario></ABApplicationHeader><ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\"><ManagedGroupRequest>false</ManagedGroupRequest></ABAuthHeader></soap:Header><soap:Body><ABGroupDelete xmlns=\"http://www.msn.com/webservices/AddressBook\"><abId>00000000-0000-0000-0000-000000000000</abId><groupFilter><groupIds><guid>%s</guid></groupIds></groupFilter></ABGroupDelete></soap:Body></soap:Envelope>"
 
+
 typedef struct _MsnContact MsnContact;
 
 struct _MsnContact
@@ -213,7 +214,7 @@
 void msn_contact_destroy(MsnContact *contact);
 
 void msn_contact_connect(MsnContact *contact);
-void msn_get_contact_list(MsnContact * contact,char * update);
+void msn_get_contact_list(MsnContact * contact, const char *update);
 void msn_get_address_book(MsnContact *contact, const char * update, const char * gupdate);
 
 /*contact SOAP Operation*/
@@ -229,6 +230,7 @@
 void msn_block_contact(MsnContact *contact,const char* membership_id);
 void msn_unblock_contact(MsnContact *contact,const char* passport);
 
+void msn_contact_connect_init(MsnSoapConn *soapconn);
 
 #endif/* _MSN_CMDPROC_H_*/
 
--- a/libgaim/protocols/msn/directconn.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/directconn.c	Sun Apr 15 03:04:05 2007 +0000
@@ -422,7 +422,6 @@
 msn_directconn_connect(MsnDirectConn *directconn, const char *host, int port)
 {
 	MsnSession *session;
-	int r;
 
 	g_return_val_if_fail(directconn != NULL, FALSE);
 	g_return_val_if_fail(host       != NULL, TRUE);
--- a/libgaim/protocols/msn/msn-utils.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/msn-utils.c	Sun Apr 15 03:04:05 2007 +0000
@@ -23,25 +23,6 @@
  */
 #include "msn.h"
 #include "msn-utils.h"
-#include "time.h"
-//#include <openssl/md5.h>
-
-/**************************************************************************
- * Util
- **************************************************************************/
-char *
-rand_guid()
-{
-	return g_strdup_printf("%4X%4X-%4X-%4X-%4X-%4X%4X%4X",
-			rand() % 0xAAFF + 0x1111,
-			rand() % 0xAAFF + 0x1111,
-			rand() % 0xAAFF + 0x1111,
-			rand() % 0xAAFF + 0x1111,
-			rand() % 0xAAFF + 0x1111,
-			rand() % 0xAAFF + 0x1111,
-			rand() % 0xAAFF + 0x1111,
-			rand() % 0xAAFF + 0x1111);
-}
 
 void
 msn_parse_format(const char *mime, char **pre_ret, char **post_ret)
@@ -146,18 +127,6 @@
 		g_free(cur);
 }
 
-/*encode the str to RFC2047 style
- * Currently only support the UTF-8 and base64 encode
- */
-char *
-msn_encode_mime(char *str)
-{
-	char *base64;
-	
-	base64 = gaim_base64_encode(str,strlen(str));
-	return g_strdup_printf("=?utf-8?B?%s?=",base64);
-}
-
 /*
  * We need this because we're only supposed to encode spaces in the font
  * names. gaim_url_encode() isn't acceptable.
@@ -382,1133 +351,14 @@
 
 	host = g_strdup(str);
 
-	if ((c = strchr(host, ':')) != NULL){
+	if ((c = strchr(host, ':')) != NULL)
+	{
 		*c = '\0';
 		port = atoi(c + 1);
-	}else{
+	}
+	else
 		port = 1863;
-	}
 
 	*ret_host = host;
 	*ret_port = port;
 }
-/***************************************************************************
- * MSN Time Related Funciton
- ***************************************************************************/
-#if 0
-int
-msn_convert_iso8601(const char *timestr,struct tm tm_time)
-{
-	char temp[64];
-	struct tm ctime;
-	time_t ts;
-
-	gaim_debug_info("MaYuan","convert string is{%s}\n",timestr);
-	tzset();
-	/*copy string first*/
-	memset(temp, 0, sizeof(temp));
-	strncpy(temp, timestr, strlen(timestr));
-
-	/*convert via strptime()*/
-	memset(&ctime, 0, sizeof(struct tm));
-	strptime(temp, "%d %b %Y %T %Z", &ctime);
-	ts = mktime(&ctime) - timezone;
-	localtime_r(&ts, tm_time);
-}
-#endif
-
-/***************************************************************************
- * MSN Challenge Computing Function
- ***************************************************************************/
-/*check the edian of system*/
-int 
-isBigEndian(void)
-{
-		short int word = 0x0100;
-		char *byte = (char *)&word;
-
-		return(byte[0]);
-}
-
-/*swap utility*/
-unsigned int 
-swapInt(unsigned int dw)
-{
-		unsigned int tmp;
-		tmp =  (dw & 0x000000FF);
-		tmp = ((dw & 0x0000FF00) >> 0x08) | (tmp << 0x08);
-		tmp = ((dw & 0x00FF0000) >> 0x10) | (tmp << 0x08);
-		tmp = ((dw & 0xFF000000) >> 0x18) | (tmp << 0x08);
-		return(tmp);
-}
-
-/*
- * Handle MSN Chanllege computation
- *This algorithm reference with http://msnpiki.msnfanatic.com/index.php/MSNP11:Challenges
- */
-#define BUFSIZE	256
-void 
-msn_handle_chl(char *input, char *output)
-{
-		GaimCipher *cipher;
-		GaimCipherContext *context;
-		char *productKey = MSNP13_WLM_PRODUCT_KEY,
-			 *productID  = MSNP13_WLM_PRODUCT_ID,
-			 *hexChars   = "0123456789abcdef",
-			 buf[BUFSIZE];
-		unsigned char md5Hash[16], *newHash;
-		unsigned int *md5Parts, *chlStringParts, newHashParts[5];
-
-		long long nHigh=0, nLow=0;
-
-		int i, bigEndian;
-
-		/* Determine our endianess */
-		bigEndian = isBigEndian();
-
-		/* Create the MD5 hash by using Gaim MD5 algorithm*/
-		cipher = gaim_ciphers_find_cipher("md5");
-		context = gaim_cipher_context_new(cipher, NULL);
-
-		gaim_cipher_context_append(context, (const guchar *)input,
-						strlen(input));
-		gaim_cipher_context_append(context, (const guchar *)productKey,
-						strlen(productKey));
-		gaim_cipher_context_digest(context, sizeof(md5Hash), md5Hash, NULL);
-		gaim_cipher_context_destroy(context);
-
-		/* Split it into four integers */
-		md5Parts = (unsigned int *)md5Hash;
-		for(i=0; i<4; i++){  
-				/* check for endianess */
-				if(bigEndian)
-						md5Parts[i] = swapInt(md5Parts[i]);
-
-				/* & each integer with 0x7FFFFFFF          */
-				/* and save one unmodified array for later */
-				newHashParts[i] = md5Parts[i];
-				md5Parts[i] &= 0x7FFFFFFF;
-		}
-
-		/* make a new string and pad with '0' */
-		snprintf(buf, BUFSIZE-5, "%s%s", input, productID);
-		i = strlen(buf);
-		memset(&buf[i], '0', 8 - (i % 8));
-		buf[i + (8 - (i % 8))]='\0';
-
-		/* split into integers */
-		chlStringParts = (unsigned int *)buf;
-
-		/* this is magic */
-		for (i=0; i<(strlen(buf)/4)-1; i+=2){
-				long long temp;
-
-				if(bigEndian){
-						chlStringParts[i]   = swapInt(chlStringParts[i]);
-						chlStringParts[i+1] = swapInt(chlStringParts[i+1]);
-				}
-
-				temp=(md5Parts[0] * (((0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF)+nHigh) + md5Parts[1])%0x7FFFFFFF;
-				nHigh=(md5Parts[2] * (((long long)chlStringParts[i+1]+temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF;
-				nLow=nLow + nHigh + temp;
-		}
-		nHigh=(nHigh+md5Parts[1]) % 0x7FFFFFFF;
-		nLow=(nLow+md5Parts[3]) % 0x7FFFFFFF;
-
-		newHashParts[0]^=nHigh;
-		newHashParts[1]^=nLow;
-		newHashParts[2]^=nHigh;
-		newHashParts[3]^=nLow;
-
-		/* swap more bytes if big endian */
-		for(i=0; i<4 && bigEndian; i++)
-				newHashParts[i] = swapInt(newHashParts[i]); 
-
-		/* make a string of the parts */
-		newHash = (unsigned char *)newHashParts;
-
-		/* convert to hexadecimal */
-		for (i=0; i<16; i++)
-		{
-				output[i*2]=hexChars[(newHash[i]>>4)&0xF];
-				output[(i*2)+1]=hexChars[newHash[i]&0xF];
-		}
-
-		output[32]='\0';
-
-//		gaim_debug_info("MaYuan","chl output{%s}\n",output);
-}
-
-#if (!defined(_XOPEN_SOURCE))||defined(_WIN32)
-
-#ifndef __P
-# if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
-#  define __P(args) args
-# else
-#  define __P(args) ()
-# endif  /* GCC.  */
-#endif  /* Not __P.  */
-
-#if ! HAVE_LOCALTIME_R && ! defined localtime_r
-# ifdef _LIBC
-#  define localtime_r __localtime_r
-# else
-/* Approximate localtime_r as best we can in its absence.  */
-#  define localtime_r my_localtime_r
-static struct tm *localtime_r __P ((const time_t *, struct tm *));
-static struct tm *
-localtime_r (t, tp)
-     const time_t *t;
-     struct tm *tp;
-{
-  struct tm *l = localtime (t);
-  if (! l)
-    return 0;
-  *tp = *l;
-  return tp;
-}
-# endif /* ! _LIBC */
-#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
-
-
-#define match_char(ch1, ch2) if (ch1 != ch2) return NULL
-
-#if defined __GNUC__ && __GNUC__ >= 2
-# define match_string(cs1, s2) \
-  ({ size_t len = strlen (cs1);						      \
-     int result = strncasecmp ((cs1), (s2), len) == 0;			      \
-     if (result) (s2) += len;						      \
-     result; })
-#else
-/* Oh come on.  Get a reasonable compiler.  */
-# define match_string(cs1, s2) \
-  (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
-#endif
-
-/* We intentionally do not use isdigit() for testing because this will
-   lead to problems with the wide character version.  */
-#define get_number(from, to, n) \
-  do {									      \
-    int __n = n;							      \
-    val = 0;								      \
-    while (*rp == ' ')							      \
-      ++rp;								      \
-    if ((*rp < '0') || (*rp > '9'))						      \
-      return NULL;							      \
-    do {								      \
-      val *= 10;							      \
-      val += *rp++ - '0';						      \
-    } while ((--__n > 0) && (val * 10 <= to) && (*rp >= '0') && (*rp <= '9'));	      \
-    if ((val < from) || (val > to))						      \
-      return NULL;							      \
-  } while (0)
-
-#ifdef _NL_CURRENT
-# define get_alt_number(from, to, n) \
-  ({									      \
-    __label__ do_normal;						      \
-    if (*decided != raw)						      \
-      {									      \
-	const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS);		      \
-	int __n = n;							      \
-	int any = 0;							      \
-	while (*rp == ' ')						      \
-	  ++rp;								      \
-	val = 0;							      \
-	do {								      \
-	  val *= 10;							      \
-	  while (*alts != '\0')						      \
-	    {								      \
-	      size_t len = strlen (alts);				      \
-	      if (strncasecmp (alts, rp, len) == 0)			      \
-	        break;							      \
-	      alts += len + 1;						      \
-	      ++val;							      \
-	    }								      \
-	  if (*alts == '\0')						      \
-	    {								      \
-	      if (*decided == not && ! any)				      \
-		goto do_normal;						      \
-	      /* If we haven't read anything it's an error.  */		      \
-	      if (! any)						      \
-		return NULL;						      \
-	      /* Correct the premature multiplication.  */		      \
-	      val /= 10;						      \
-	      break;							      \
-	    }								      \
-	  else								      \
-	    *decided = loc;						      \
-	} while (--__n > 0 && val * 10 <= to);				      \
-	if (val < from || val > to)					      \
-	  return NULL;							      \
-      }									      \
-    else								      \
-      {									      \
-       do_normal:							      \
-        get_number (from, to, n);					      \
-      }									      \
-    0;									      \
-  })
-#else
-# define get_alt_number(from, to, n) \
-  /* We don't have the alternate representation.  */			      \
-  get_number(from, to, n)
-#endif
-
-#define recursive(new_fmt) \
-  (*(new_fmt) != '\0'							      \
-   && (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL)
-
-
-#ifdef _LIBC
-/* This is defined in locale/C-time.c in the GNU libc.  */
-extern const struct locale_data _nl_C_LC_TIME;
-extern const unsigned short int __mon_yday[2][13];
-
-# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
-# define ab_weekday_name \
-  (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
-# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
-# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
-# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
-# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string)
-# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
-# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
-# define HERE_T_FMT_AMPM \
-  (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
-# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
-
-# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n)
-#else
-static char const weekday_name[][10] =
-  {
-    "Sunday", "Monday", "Tuesday", "Wednesday",
-    "Thursday", "Friday", "Saturday"
-  };
-static char const ab_weekday_name[][4] =
-  {
-    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-  };
-static char const month_name[][10] =
-  {
-    "January", "February", "March", "April", "May", "June",
-    "July", "August", "September", "October", "November", "December"
-  };
-static char const ab_month_name[][4] =
-  {
-    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-  };
-# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
-# define HERE_D_FMT "%m/%d/%y"
-# define HERE_AM_STR "AM"
-# define HERE_PM_STR "PM"
-# define HERE_T_FMT_AMPM "%I:%M:%S %p"
-# define HERE_T_FMT "%H:%M:%S"
-
-const unsigned short int __mon_yday[2][13] =
-  {
-    /* Normal years.  */
-    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
-    /* Leap years.  */
-    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
-  };
-#endif
-
-/* Status of lookup: do we use the locale data or the raw data?  */
-enum locale_status { not, loc, raw };
-
-
-#ifndef __isleap
-/* Nonzero if YEAR is a leap year (every 4 years,
-   except every 100th isn't, and every 400th is).  */
-# define __isleap(year)	\
-  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
-#endif
-
-/* Compute the day of the week.  */
-static void
-day_of_the_week (struct tm *tm)
-{
-  /* We know that January 1st 1970 was a Thursday (= 4).  Compute the
-     the difference between this data in the one on TM and so determine
-     the weekday.  */
-  int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2);
-  int wday = (-473
-	      + (365 * (tm->tm_year - 70))
-	      + (corr_year / 4)
-	      - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
-	      + (((corr_year / 4) / 25) / 4)
-	      + __mon_yday[0][tm->tm_mon]
-	      + tm->tm_mday - 1);
-  tm->tm_wday = ((wday % 7) + 7) % 7;
-}
-
-/* Compute the day of the year.  */
-static void
-day_of_the_year (struct tm *tm)
-{
-  tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon]
-		 + (tm->tm_mday - 1));
-}
-
-static char *
-#ifdef _LIBC
-internal_function
-#endif
-strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm,
-			enum locale_status *decided, int era_cnt));
-
-static char *
-#ifdef _LIBC
-internal_function
-#endif
-strptime_internal (rp, fmt, tm, decided, era_cnt)
-     const char *rp;
-     const char *fmt;
-     struct tm *tm;
-     enum locale_status *decided;
-     int era_cnt;
-{
-  const char *rp_backup;
-  int cnt;
-  size_t val;
-  int have_I, is_pm;
-  int century, want_century;
-  int want_era;
-  int have_wday, want_xday;
-  int have_yday;
-  int have_mon, have_mday;
-#ifdef _NL_CURRENT
-  size_t num_eras;
-#endif
-  struct era_entry *era;
-
-  have_I = is_pm = 0;
-  century = -1;
-  want_century = 0;
-  want_era = 0;
-  era = NULL;
-
-  have_wday = want_xday = have_yday = have_mon = have_mday = 0;
-
-  while (*fmt != '\0')
-    {
-      /* A white space in the format string matches 0 more or white
-	 space in the input string.  */
-      if (isspace (*fmt))
-	{
-	  while (isspace (*rp))
-	    ++rp;
-	  ++fmt;
-	  continue;
-	}
-
-      /* Any character but `%' must be matched by the same character
-	 in the iput string.  */
-      if (*fmt != '%')
-	{
-	  match_char (*fmt++, *rp++);
-	  continue;
-	}
-
-      ++fmt;
-#ifndef _NL_CURRENT
-      /* We need this for handling the `E' modifier.  */
-    start_over:
-#endif
-
-      /* Make back up of current processing pointer.  */
-      rp_backup = rp;
-
-      switch (*fmt++)
-	{
-	case '%':
-	  /* Match the `%' character itself.  */
-	  match_char ('%', *rp++);
-	  break;
-	case 'a':
-	case 'A':
-	  /* Match day of week.  */
-	  for (cnt = 0; cnt < 7; ++cnt)
-	    {
-#ifdef _NL_CURRENT
-	      if (*decided !=raw)
-		{
-		  if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
-		    {
-		      if (*decided == not
-			  && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
-				     weekday_name[cnt]))
-			*decided = loc;
-		      break;
-		    }
-		  if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
-		    {
-		      if (*decided == not
-			  && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
-				     ab_weekday_name[cnt]))
-			*decided = loc;
-		      break;
-		    }
-		}
-#endif
-	      if (*decided != loc
-		  && (match_string (weekday_name[cnt], rp)
-		      || match_string (ab_weekday_name[cnt], rp)))
-		{
-		  *decided = raw;
-		  break;
-		}
-	    }
-	  if (cnt == 7)
-	    /* Does not match a weekday name.  */
-	    return NULL;
-	  tm->tm_wday = cnt;
-	  have_wday = 1;
-	  break;
-	case 'b':
-	case 'B':
-	case 'h':
-	  /* Match month name.  */
-	  for (cnt = 0; cnt < 12; ++cnt)
-	    {
-#ifdef _NL_CURRENT
-	      if (*decided !=raw)
-		{
-		  if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
-		    {
-		      if (*decided == not
-			  && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
-				     month_name[cnt]))
-			*decided = loc;
-		      break;
-		    }
-		  if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
-		    {
-		      if (*decided == not
-			  && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
-				     ab_month_name[cnt]))
-			*decided = loc;
-		      break;
-		    }
-		}
-#endif
-	      if (match_string (month_name[cnt], rp)
-		  || match_string (ab_month_name[cnt], rp))
-		{
-		  *decided = raw;
-		  break;
-		}
-	    }
-	  if (cnt == 12)
-	    /* Does not match a month name.  */
-	    return NULL;
-	  tm->tm_mon = cnt;
-	  want_xday = 1;
-	  break;
-	case 'c':
-	  /* Match locale's date and time format.  */
-#ifdef _NL_CURRENT
-	  if (*decided != raw)
-	    {
-	      if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
-		{
-		  if (*decided == loc)
-		    return NULL;
-		  else
-		    rp = rp_backup;
-		}
-	      else
-		{
-		  if (*decided == not &&
-		      strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
-		    *decided = loc;
-		  want_xday = 1;
-		  break;
-		}
-	      *decided = raw;
-	    }
-#endif
-	  if (!recursive (HERE_D_T_FMT))
-	    return NULL;
-	  want_xday = 1;
-	  break;
-	case 'C':
-	  /* Match century number.  */
-#ifdef _NL_CURRENT
-	match_century:
-#endif
-	  get_number (0, 99, 2);
-	  century = val;
-	  want_xday = 1;
-	  break;
-	case 'd':
-	case 'e':
-	  /* Match day of month.  */
-	  get_number (1, 31, 2);
-	  tm->tm_mday = val;
-	  have_mday = 1;
-	  want_xday = 1;
-	  break;
-	case 'F':
-	  if (!recursive ("%Y-%m-%d"))
-	    return NULL;
-	  want_xday = 1;
-	  break;
-	case 'x':
-#ifdef _NL_CURRENT
-	  if (*decided != raw)
-	    {
-	      if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
-		{
-		  if (*decided == loc)
-		    return NULL;
-		  else
-		    rp = rp_backup;
-		}
-	      else
-		{
-		  if (*decided == not
-		      && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
-		    *decided = loc;
-		  want_xday = 1;
-		  break;
-		}
-	      *decided = raw;
-	    }
-#endif
-	  /* Fall through.  */
-	case 'D':
-	  /* Match standard day format.  */
-	  if (!recursive (HERE_D_FMT))
-	    return NULL;
-	  want_xday = 1;
-	  break;
-	case 'k':
-	case 'H':
-	  /* Match hour in 24-hour clock.  */
-	  get_number (0, 23, 2);
-	  tm->tm_hour = val;
-	  have_I = 0;
-	  break;
-	case 'I':
-	  /* Match hour in 12-hour clock.  */
-	  get_number (1, 12, 2);
-	  tm->tm_hour = val % 12;
-	  have_I = 1;
-	  break;
-	case 'j':
-	  /* Match day number of year.  */
-	  get_number (1, 366, 3);
-	  tm->tm_yday = val - 1;
-	  have_yday = 1;
-	  break;
-	case 'm':
-	  /* Match number of month.  */
-	  get_number (1, 12, 2);
-	  tm->tm_mon = val - 1;
-	  have_mon = 1;
-	  want_xday = 1;
-	  break;
-	case 'M':
-	  /* Match minute.  */
-	  get_number (0, 59, 2);
-	  tm->tm_min = val;
-	  break;
-	case 'n':
-	case 't':
-	  /* Match any white space.  */
-	  while (isspace (*rp))
-	    ++rp;
-	  break;
-	case 'p':
-	  /* Match locale's equivalent of AM/PM.  */
-#ifdef _NL_CURRENT
-	  if (*decided != raw)
-	    {
-	      if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
-		{
-		  if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
-		    *decided = loc;
-		  break;
-		}
-	      if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
-		{
-		  if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
-		    *decided = loc;
-		  is_pm = 1;
-		  break;
-		}
-	      *decided = raw;
-	    }
-#endif
-	  if (!match_string (HERE_AM_STR, rp))
-	    if (match_string (HERE_PM_STR, rp))
-	      is_pm = 1;
-	    else
-	      return NULL;
-	  break;
-	case 'r':
-#ifdef _NL_CURRENT
-	  if (*decided != raw)
-	    {
-	      if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
-		{
-		  if (*decided == loc)
-		    return NULL;
-		  else
-		    rp = rp_backup;
-		}
-	      else
-		{
-		  if (*decided == not &&
-		      strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
-			      HERE_T_FMT_AMPM))
-		    *decided = loc;
-		  break;
-		}
-	      *decided = raw;
-	    }
-#endif
-	  if (!recursive (HERE_T_FMT_AMPM))
-	    return NULL;
-	  break;
-	case 'R':
-	  if (!recursive ("%H:%M"))
-	    return NULL;
-	  break;
-	case 's':
-	  {
-	    /* The number of seconds may be very high so we cannot use
-	       the `get_number' macro.  Instead read the number
-	       character for character and construct the result while
-	       doing this.  */
-	    time_t secs = 0;
-	    if (*rp < '0' || *rp > '9')
-	      /* We need at least one digit.  */
-	      return NULL;
-
-	    do
-	      {
-		secs *= 10;
-		secs += *rp++ - '0';
-	      }
-	    while (*rp >= '0' && *rp <= '9');
-
-	    if (localtime_r (&secs, tm) == NULL)
-	      /* Error in function.  */
-	      return NULL;
-	  }
-	  break;
-	case 'S':
-	  get_number (0, 61, 2);
-	  tm->tm_sec = val;
-	  break;
-	case 'X':
-#ifdef _NL_CURRENT
-	  if (*decided != raw)
-	    {
-	      if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
-		{
-		  if (*decided == loc)
-		    return NULL;
-		  else
-		    rp = rp_backup;
-		}
-	      else
-		{
-		  if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
-		    *decided = loc;
-		  break;
-		}
-	      *decided = raw;
-	    }
-#endif
-	  /* Fall through.  */
-	case 'T':
-	  if (!recursive (HERE_T_FMT))
-	    return NULL;
-	  break;
-	case 'u':
-	  get_number (1, 7, 1);
-	  tm->tm_wday = val % 7;
-	  have_wday = 1;
-	  break;
-	case 'g':
-	  get_number (0, 99, 2);
-	  /* XXX This cannot determine any field in TM.  */
-	  break;
-	case 'G':
-	  if (*rp < '0' || *rp > '9')
-	    return NULL;
-	  /* XXX Ignore the number since we would need some more
-	     information to compute a real date.  */
-	  do
-	    ++rp;
-	  while (*rp >= '0' && *rp <= '9');
-	  break;
-	case 'U':
-	case 'V':
-	case 'W':
-	  get_number (0, 53, 2);
-	  /* XXX This cannot determine any field in TM without some
-	     information.  */
-	  break;
-	case 'w':
-	  /* Match number of weekday.  */
-	  get_number (0, 6, 1);
-	  tm->tm_wday = val;
-	  have_wday = 1;
-	  break;
-	case 'y':
-#ifdef _NL_CURRENT
-	match_year_in_century:
-#endif
-	  /* Match year within century.  */
-	  get_number (0, 99, 2);
-	  /* The "Year 2000: The Millennium Rollover" paper suggests that
-	     values in the range 69-99 refer to the twentieth century.  */
-	  tm->tm_year = val >= 69 ? val : val + 100;
-	  /* Indicate that we want to use the century, if specified.  */
-	  want_century = 1;
-	  want_xday = 1;
-	  break;
-	case 'Y':
-	  /* Match year including century number.  */
-	  get_number (0, 9999, 4);
-	  tm->tm_year = val - 1900;
-	  want_century = 0;
-	  want_xday = 1;
-	  break;
-	case 'Z':
-	  /* XXX How to handle this?  */
-	  break;
-	case 'E':
-#ifdef _NL_CURRENT
-	  switch (*fmt++)
-	    {
-	    case 'c':
-	      /* Match locale's alternate date and time format.  */
-	      if (*decided != raw)
-		{
-		  const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
-
-		  if (*fmt == '\0')
-		    fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
-
-		  if (!recursive (fmt))
-		    {
-		      if (*decided == loc)
-			return NULL;
-		      else
-			rp = rp_backup;
-		    }
-		  else
-		    {
-		      if (strcmp (fmt, HERE_D_T_FMT))
-			*decided = loc;
-		      want_xday = 1;
-		      break;
-		    }
-		  *decided = raw;
-		}
-	      /* The C locale has no era information, so use the
-		 normal representation.  */
-	      if (!recursive (HERE_D_T_FMT))
-		return NULL;
-	      want_xday = 1;
-	      break;
-	    case 'C':
-	      if (*decided != raw)
-		{
-		  if (era_cnt >= 0)
-		    {
-		      era = _nl_select_era_entry (era_cnt);
-		      if (match_string (era->era_name, rp))
-			{
-			  *decided = loc;
-			  break;
-			}
-		      else
-			return NULL;
-		    }
-		  else
-		    {
-		      num_eras = _NL_CURRENT_WORD (LC_TIME,
-						   _NL_TIME_ERA_NUM_ENTRIES);
-		      for (era_cnt = 0; era_cnt < (int) num_eras;
-			   ++era_cnt, rp = rp_backup)
-			{
-			  era = _nl_select_era_entry (era_cnt);
-			  if (match_string (era->era_name, rp))
-			    {
-			      *decided = loc;
-			      break;
-			    }
-			}
-		      if (era_cnt == (int) num_eras)
-			{
-			  era_cnt = -1;
-			  if (*decided == loc)
-			    return NULL;
-			}
-		      else
-			break;
-		    }
-
-		  *decided = raw;
-		}
-	      /* The C locale has no era information, so use the
-		 normal representation.  */
-	      goto match_century;
- 	    case 'y':
-	      if (*decided == raw)
-		goto match_year_in_century;
-
-	      get_number(0, 9999, 4);
-	      tm->tm_year = val;
-	      want_era = 1;
-	      want_xday = 1;
-	      break;
-	    case 'Y':
-	      if (*decided != raw)
-		{
-		  num_eras = _NL_CURRENT_WORD (LC_TIME,
-					       _NL_TIME_ERA_NUM_ENTRIES);
-		  for (era_cnt = 0; era_cnt < (int) num_eras;
-		       ++era_cnt, rp = rp_backup)
-		    {
-		      era = _nl_select_era_entry (era_cnt);
-		      if (recursive (era->era_format))
-			break;
-		    }
-		  if (era_cnt == (int) num_eras)
-		    {
-		      era_cnt = -1;
-		      if (*decided == loc)
-			return NULL;
-		      else
-			rp = rp_backup;
-		    }
-		  else
-		    {
-		      *decided = loc;
-		      era_cnt = -1;
-		      break;
-		    }
-
-		  *decided = raw;
-		}
-	      get_number (0, 9999, 4);
-	      tm->tm_year = val - 1900;
-	      want_century = 0;
-	      want_xday = 1;
-	      break;
-	    case 'x':
-	      if (*decided != raw)
-		{
-		  const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
-
-		  if (*fmt == '\0')
-		    fmt = _NL_CURRENT (LC_TIME, D_FMT);
-
-		  if (!recursive (fmt))
-		    {
-		      if (*decided == loc)
-			return NULL;
-		      else
-			rp = rp_backup;
-		    }
-		  else
-		    {
-		      if (strcmp (fmt, HERE_D_FMT))
-			*decided = loc;
-		      break;
-		    }
-		  *decided = raw;
-		}
-	      if (!recursive (HERE_D_FMT))
-		return NULL;
-	      break;
-	    case 'X':
-	      if (*decided != raw)
-		{
-		  const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
-
-		  if (*fmt == '\0')
-		    fmt = _NL_CURRENT (LC_TIME, T_FMT);
-
-		  if (!recursive (fmt))
-		    {
-		      if (*decided == loc)
-			return NULL;
-		      else
-			rp = rp_backup;
-		    }
-		  else
-		    {
-		      if (strcmp (fmt, HERE_T_FMT))
-			*decided = loc;
-		      break;
-		    }
-		  *decided = raw;
-		}
-	      if (!recursive (HERE_T_FMT))
-		return NULL;
-	      break;
-	    default:
-	      return NULL;
-	    }
-	  break;
-#else
-	  /* We have no information about the era format.  Just use
-	     the normal format.  */
-	  if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
-	      && *fmt != 'x' && *fmt != 'X')
-	    /* This is an illegal format.  */
-	    return NULL;
-
-	  goto start_over;
-#endif
-	case 'O':
-	  switch (*fmt++)
-	    {
-	    case 'd':
-	    case 'e':
-	      /* Match day of month using alternate numeric symbols.  */
-	      get_alt_number (1, 31, 2);
-	      tm->tm_mday = val;
-	      have_mday = 1;
-	      want_xday = 1;
-	      break;
-	    case 'H':
-	      /* Match hour in 24-hour clock using alternate numeric
-		 symbols.  */
-	      get_alt_number (0, 23, 2);
-	      tm->tm_hour = val;
-	      have_I = 0;
-	      break;
-	    case 'I':
-	      /* Match hour in 12-hour clock using alternate numeric
-		 symbols.  */
-	      get_alt_number (1, 12, 2);
-	      tm->tm_hour = val - 1;
-	      have_I = 1;
-	      break;
-	    case 'm':
-	      /* Match month using alternate numeric symbols.  */
-	      get_alt_number (1, 12, 2);
-	      tm->tm_mon = val - 1;
-	      have_mon = 1;
-	      want_xday = 1;
-	      break;
-	    case 'M':
-	      /* Match minutes using alternate numeric symbols.  */
-	      get_alt_number (0, 59, 2);
-	      tm->tm_min = val;
-	      break;
-	    case 'S':
-	      /* Match seconds using alternate numeric symbols.  */
-	      get_alt_number (0, 61, 2);
-	      tm->tm_sec = val;
-	      break;
-	    case 'U':
-	    case 'V':
-	    case 'W':
-	      get_alt_number (0, 53, 2);
-	      /* XXX This cannot determine any field in TM without
-		 further information.  */
-	      break;
-	    case 'w':
-	      /* Match number of weekday using alternate numeric symbols.  */
-	      get_alt_number (0, 6, 1);
-	      tm->tm_wday = val;
-	      have_wday = 1;
-	      break;
-	    case 'y':
-	      /* Match year within century using alternate numeric symbols.  */
-	      get_alt_number (0, 99, 2);
-	      tm->tm_year = val >= 69 ? val : val + 100;
-	      want_xday = 1;
-	      break;
-	    default:
-	      return NULL;
-	    }
-	  break;
-	default:
-	  return NULL;
-	}
-    }
-
-  if (have_I && is_pm)
-    tm->tm_hour += 12;
-
-  if (century != -1)
-    {
-      if (want_century)
-	tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
-      else
-	/* Only the century, but not the year.  Strange, but so be it.  */
-	tm->tm_year = (century - 19) * 100;
-    }
-
-#ifdef _NL_CURRENT
-  if (era_cnt != -1)
-    {
-      era = _nl_select_era_entry(era_cnt);
-      if (want_era)
-	tm->tm_year = (era->start_date[0]
-		       + ((tm->tm_year - era->offset)
-			  * era->absolute_direction));
-      else
-	/* Era start year assumed.  */
-	tm->tm_year = era->start_date[0];
-    }
-  else
-#endif
-    if (want_era)
-      return NULL;
-
-  if (want_xday && !have_wday)
-    {
-      if ( !(have_mon && have_mday) && have_yday)
-	{
-	  /* We don't have tm_mon and/or tm_mday, compute them.  */
-	  int t_mon = 0;
-	  while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
-	      t_mon++;
-	  if (!have_mon)
-	      tm->tm_mon = t_mon - 1;
-	  if (!have_mday)
-	      tm->tm_mday =
-		(tm->tm_yday
-		 - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1);
-	}
-      day_of_the_week (tm);
-    }
-  if (want_xday && !have_yday)
-    day_of_the_year (tm);
-
-  return (char *) rp;
-}
-
-
-char *
-msn_strptime (buf, format, tm)
-     const char *buf;
-     const char *format;
-     struct tm *tm;
-{
-  enum locale_status decided;
-
-#ifdef _NL_CURRENT
-  decided = not;
-#else
-  decided = raw;
-#endif
-  return strptime_internal (buf, format, tm, &decided, -1);
-}
-#else
-#define msn_strptime	strptime
-#endif
--- a/libgaim/protocols/msn/msn-utils.h	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/msn-utils.h	Sun Apr 15 03:04:05 2007 +0000
@@ -24,14 +24,6 @@
 #ifndef _MSN_UTILS_H_
 #define _MSN_UTILS_H_
 
-/*encode the str to RFC2047 style*/
-char * msn_encode_mime(char *str);
-
-/**
- * Generate the Random GUID
- */
-char * rand_guid();
-
 /**
  * Parses the MSN message formatting into a format compatible with Gaim.
  *
@@ -55,10 +47,5 @@
 void msn_import_html(const char *html, char **attributes, char **message);
 
 void msn_parse_socket(const char *str, char **ret_host, int *ret_port);
-void msn_handle_chl(char *input, char *output);
-int isBigEndian(void);
-unsigned int swapInt(unsigned int dw);
-char * msn_strptime (const char *buf,const char *format,struct tm *tm);
-
 
 #endif /* _MSN_UTILS_H_ */
--- a/libgaim/protocols/msn/msn.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/msn.c	Sun Apr 15 03:04:05 2007 +0000
@@ -36,7 +36,7 @@
 #include "util.h"
 #include "cmds.h"
 #include "prpl.h"
-#include "msn-utils.h"
+#include "msnutils.h"
 #include "version.h"
 
 #include "switchboard.h"
@@ -113,7 +113,7 @@
 	return GAIM_CMD_RET_OK;
 }
 
-static void
+void
 msn_act_id(GaimConnection *gc, const char *entry)
 {
 	MsnCmdProc *cmdproc;
@@ -121,6 +121,9 @@
 	GaimAccount *account;
 	const char *alias;
 
+	char *soapbody;
+	MsnSoapReq *soap_request;
+
 	session = gc->proto_data;
 	cmdproc = session->notification->cmdproc;
 	account = gaim_connection_get_account(gc);
@@ -137,9 +140,27 @@
 		return;
 	}
 
-	msn_cmdproc_send(cmdproc, "REA", "%s %s",
-					 gaim_account_get_username(account),
-					 alias);
+	if (*alias == '\0') {
+		alias = gaim_url_encode(gaim_account_get_username(account));
+	}
+
+	msn_cmdproc_send(cmdproc, "PRP", "MFN %s", alias);
+
+	soapbody = g_strdup_printf(MSN_CONTACT_UPDATE_TEMPLATE, alias);
+	/*build SOAP and POST it*/
+	soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
+										MSN_ADDRESS_BOOK_POST_URL,
+										MSN_CONTACT_UPDATE_SOAP_ACTION,
+										soapbody,
+										NULL,
+										NULL);
+
+	session->contact->soapconn->read_cb = NULL;
+	msn_soap_post(session->contact->soapconn,
+				  soap_request,
+				  msn_contact_connect_init);
+
+	g_free(soapbody);
 }
 
 static void
@@ -524,7 +545,8 @@
 {
 	GaimPresence *presence;
 	GaimStatus *status;
-	char *msg, *psm_str, *tmp2, *text, *name;
+	const char *msg, *name;
+	char *psm_str, *tmp2, *text;
 
 	presence = gaim_buddy_get_presence(buddy);
 	status = gaim_presence_get_active_status(presence);
@@ -903,9 +925,8 @@
 
 		oim = session->oim;
 		friendname = msn_encode_mime(account->username);
-		msn_oim_prep_send_msg_info(oim,
-			gaim_account_get_username(account),friendname,who,
-			message);
+		msn_oim_prep_send_msg_info(oim, gaim_account_get_username(account),
+								   friendname, who,	message);
 		msn_oim_send_msg(oim);
 	}
 	return 1;
--- a/libgaim/protocols/msn/msn.h	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/msn.h	Sun Apr 15 03:04:05 2007 +0000
@@ -141,4 +141,7 @@
 	 (MSN_CLIENT_ID_RESERVED_2 <<  8) | \
 	 (MSN_CLIENT_ID_CAPABILITIES))
 
+void msn_act_id(GaimConnection *gc, const char *entry);
+
+
 #endif /* _MSN_H_ */
--- a/libgaim/protocols/msn/notification.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/notification.c	Sun Apr 15 03:04:05 2007 +0000
@@ -25,7 +25,7 @@
 #include "notification.h"
 #include "state.h"
 #include "error.h"
-#include "msn-utils.h"
+#include "msnutils.h"
 #include "page.h"
 
 #include "userlist.h"
@@ -37,9 +37,10 @@
 /****************************************************************************
  * 	Local Function Prototype
  ****************************************************************************/
-void msn_notification_post_adl(MsnCmdProc *cmdproc,char *payload ,int payload_len);
 
-void msn_add_contact_xml(xmlnode *mlNode,const char *passport,int list_op,int type);
+static void msn_notification_fqy_yahoo(MsnSession *session, const char *passport);
+static void msn_notification_post_adl(MsnCmdProc *cmdproc, char *payload, int payload_len);
+static void msn_add_contact_xml(xmlnode *mlNode, const char *passport, int list_op, int type);
 
 /**************************************************************************
  * Main
@@ -233,15 +234,17 @@
 
 	if (!g_ascii_strcasecmp(cmd->params[1], "OK")){
 		/* authenticate OK */
+		/* friendly name part no longer true in msnp11 */
+#if 0
 		const char *friendly = gaim_url_decode(cmd->params[3]);
 
 		gaim_connection_set_display_name(gc, friendly);
-
+#endif
 		msn_session_set_login_step(session, MSN_LOGIN_STEP_SYN);
 
 //		msn_cmdproc_send(cmdproc, "SYN", "%s", "0");
 		//TODO we should use SOAP contact to fetch contact list
-	}else if (!g_ascii_strcasecmp(cmd->params[1], "TWN")){
+	} else if (!g_ascii_strcasecmp(cmd->params[1], "TWN")){
 		/* Passport authentication */
 		char **elems, **cur, **tokens;
 
@@ -561,7 +564,7 @@
  * Buddy Lists
  **************************************************************************/
 /* add contact to xmlnode */
-void 
+static void 
 msn_add_contact_xml(xmlnode *mlNode,const char *passport,int list_op,int type)
 {
 	xmlnode *d_node,*c_node;
@@ -622,8 +625,8 @@
 	g_free(tokens);
 }
 
-void
-msn_notification_post_adl(MsnCmdProc *cmdproc,char *payload, int payload_len)
+static void
+msn_notification_post_adl(MsnCmdProc *cmdproc, char *payload, int payload_len)
 {
 	MsnTransaction *trans;
 
@@ -643,6 +646,7 @@
 	xmlnode *adl_node;
 	char *payload;
 	int payload_len;
+	const char *display_name;
 
 	userlist = session->userlist;
 	adl_node = xmlnode_new("ml");
@@ -659,11 +663,18 @@
 	xmlnode_free(adl_node);
 
 	msn_notification_post_adl(session->notification->cmdproc,payload,payload_len);
+
+	display_name = gaim_connection_get_display_name(session->account->gc);
+	if (display_name && strcmp(display_name,
+							   gaim_account_get_username(session->account))) {
+		msn_act_id(session->account->gc, display_name);
+	}
+
 }
 
 /*Post FQY to NS,Inform add a Yahoo User*/
-void
-msn_notification_fqy_yahoo(MsnSession *session,char *passport)
+static void
+msn_notification_fqy_yahoo(MsnSession *session, const char *passport)
 {
 	MsnTransaction *trans;
 	MsnCmdProc *cmdproc;
@@ -715,8 +726,10 @@
 static void
 rml_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
+#if 0
 	MsnTransaction *trans;
 	char * payload;
+#endif
 
 	gaim_debug_info("MaYuan","Process ADL\n");
 #if 0
@@ -820,7 +833,7 @@
 
 	group_name = gaim_url_decode(cmd->params[2]);
 
-	msn_group_new(session->userlist, group_id, group_name);
+	msn_group_new(session->userlist, cmd->params[3], group_name);
 
 	/* There is a user that must me moved to this group */
 	if (cmd->trans->data)
@@ -1045,6 +1058,12 @@
 			msn_user_set_work_phone(session->user, NULL);
 		else if (!strcmp(type, "PHM"))
 			msn_user_set_mobile_phone(session->user, NULL);
+		else if (!strcmp(type, "MFM")) {
+			type = cmd->params[1];
+			gaim_connection_set_display_name(
+				gaim_account_get_connection(session->account),
+				gaim_url_decode(cmd->params[2]));
+		}
 	}
 }
 
@@ -1052,11 +1071,10 @@
 reg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
 	MsnSession *session;
-	int group_id;
-	const char *group_name;
+	const char *group_id, *group_name;
 
 	session = cmdproc->session;
-	group_id = atoi(cmd->params[2]);
+	group_id = cmd->params[2];
 	group_name = gaim_url_decode(cmd->params[3]);
 
 	msn_userlist_rename_group_id(session->userlist, group_id, group_name);
@@ -1082,10 +1100,8 @@
 {
 	MsnSession *session;
 	MsnUser *user;
-	const char *list;
-	const char *passport;
+	const char *group_id, *list, *passport;
 	MsnListId list_id;
-	int group_id;
 
 	session = cmdproc->session;
 	list = cmd->params[1];
@@ -1097,9 +1113,9 @@
 	list_id = msn_get_list_id(list);
 
 	if (cmd->param_count == 5)
-		group_id = atoi(cmd->params[4]);
+		group_id = cmd->params[4];
 	else
-		group_id = -1;
+		group_id = NULL;
 
 	msn_got_rem_user(session, user, list_id, group_id);
 	msn_user_update(user);
@@ -1109,10 +1125,10 @@
 rmg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
 	MsnSession *session;
-	int group_id;
+	const char *group_id;
 
 	session = cmdproc->session;
-	group_id = atoi(cmd->params[2]);
+	group_id = cmd->params[2];
 
 	msn_userlist_remove_group_id(session->userlist, group_id);
 }
@@ -1120,7 +1136,7 @@
 static void
 rmg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
 {
-	int group_id;
+	const char *group_id;
 	char **params;
 
 	params = g_strsplit(trans->params, " ", 0);
@@ -1412,7 +1428,8 @@
 	GaimAccount *account;
 	GaimConnection *gc;
 	MsnUser *user;
-	const char *passport, *psm_str;
+	const char *passport;
+	char *psm_str;
 
 	/*get the payload content*/
 //	gaim_debug_info("MaYuan","UBX {%s} payload{%s}\n",cmd->params[0], cmd->payload);
@@ -1507,7 +1524,7 @@
 	msn_session_set_bnode(session);
 	session->contact = msn_contact_new(session);
 	clLastChange = gaim_blist_node_get_string(msn_session_get_bnode(session),"CLLastChange");
-	msn_get_contact_list(session->contact,clLastChange);
+	msn_get_contact_list(session->contact, clLastChange);
 //	msn_contact_connect(session->contact);
 }
 
@@ -1738,7 +1755,6 @@
 						   const char *group_id)
 {
 	MsnCmdProc *cmdproc;
-	MsnTransaction *trans;
 	xmlnode *adl_node;
 	char *payload;
 	int payload_len;
--- a/libgaim/protocols/msn/oim.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/oim.c	Sun Apr 15 03:04:05 2007 +0000
@@ -26,13 +26,22 @@
 #include "msn.h"
 #include "soap.h"
 #include "oim.h"
-#include "msn-utils.h"
+#include "msnutils.h"
 
 /*Local Function Prototype*/
 static void msn_oim_post_single_get_msg(MsnOim *oim,const char *msgid);
-void msn_oim_retrieve_connect_init(MsnSoapConn *soapconn);
-void msn_oim_send_connect_init(MsnSoapConn *soapconn);
-void msn_oim_free_send_req(MsnOimSendReq *req);
+static MsnOimSendReq *msn_oim_new_send_req(const char *from_member,
+										   const char *friendname,
+										   const char* to_member,
+										   gint send_seq,
+										   const char *msg);
+static void msn_oim_retrieve_connect_init(MsnSoapConn *soapconn);
+static void msn_oim_send_connect_init(MsnSoapConn *soapconn);
+static void msn_oim_free_send_req(MsnOimSendReq *req);
+static void msn_oim_report_to_user(MsnOim *oim, char *msg_str);
+static void msn_oim_get_process(MsnOim *oim, char *oim_msg);
+static char *msn_oim_msg_to_str(MsnOim *oim, const char *body);
+const void msn_oim_send_process(MsnOim *oim, const char *body, int len);
 
 /*new a OIM object*/
 MsnOim *
@@ -73,11 +82,10 @@
 	g_free(oim);
 }
 
-MsnOimSendReq *
-msn_oim_new_send_req(char *from_member,
-				char*friendname,char* to_member,
-				gint send_seq,
-				char *msg)
+static MsnOimSendReq *
+msn_oim_new_send_req(const char *from_member, const char*friendname,
+					 const char* to_member, gint send_seq,
+					 const char *msg)
 {
 	MsnOimSendReq *request;
 	
@@ -90,7 +98,7 @@
 	return request;
 }
 
-void
+static void
 msn_oim_free_send_req(MsnOimSendReq *req)
 {
 	g_return_if_fail(req != NULL);
@@ -107,8 +115,8 @@
  * OIM send SOAP request
  * **************************************/
 /*encode the message to OIM Message Format*/
-char * 
-msn_oim_msg_to_str(MsnOim *oim,char *body)
+static char *
+msn_oim_msg_to_str(MsnOim *oim, const char *body)
 {
 	char *oim_body,*oim_base64;
 	
@@ -154,14 +162,13 @@
  * Process the send return SOAP string
  * If got SOAP Fault,get the lock key,and resend it.
  */
-void
-msn_oim_send_process(MsnOim *oim,char *body,int len)
+const void
+msn_oim_send_process(MsnOim *oim, const char *body, int len)
 {
-	xmlnode *responseNode,*bodyNode;
-	xmlnode	*faultNode,*faultCodeNode,*faultstringNode;
-	xmlnode *detailNode,*challengeNode;
-	char *faultCodeStr,*faultstring;
-	char *challenge;
+	xmlnode *responseNode, *bodyNode;
+	xmlnode	*faultNode, *faultCodeNode, *faultstringNode;
+	xmlnode *detailNode, *challengeNode;
+	char *faultCodeStr, *faultstring;
 
 	responseNode = xmlnode_from_str(body,len);
 	g_return_if_fail(responseNode != NULL);
@@ -245,9 +252,9 @@
 }
 
 void
-msn_oim_prep_send_msg_info(MsnOim *oim,
-					char *membername,char*friendname,char *tomember,
-					char * msg)
+msn_oim_prep_send_msg_info(MsnOim *oim, const char *membername,
+						   const char* friendname, const char *tomember,
+						   const char * msg)
 {
 	MsnOimSendReq *request;
 
@@ -324,7 +331,6 @@
 				 GaimInputCondition cond)
 {
 	MsnSoapConn * soapconn = data;	
-	MsnOim * oim = soapconn->session->oim;
 
 	gaim_debug_info("MaYuan","OIM delete read buffer:{%s}\n",soapconn->body);
 
@@ -404,8 +410,8 @@
 }
 
 /*Post the Offline Instant Message to User Conversation*/
-void
-msn_oim_report_to_user(MsnOim *oim,char *msg_str)
+static void
+msn_oim_report_to_user(MsnOim *oim, char *msg_str)
 {
 	MsnMessage *message;
 	char *date,*from,*decode_msg;
@@ -413,13 +419,13 @@
 	char **tokens;
 	char *start,*end;
 	int has_nick = 0;
-	char *passport_str,*passport;
+	char *passport_str, *passport;
 	char *msg_id;
 
 	message = msn_message_new(MSN_MSG_UNKNOWN);
 
-	msn_message_parse_payload(message,msg_str,strlen(msg_str),
-					MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM);
+	msn_message_parse_payload(message, msg_str, strlen(msg_str),
+							  MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM);
 	gaim_debug_info("MaYuan","oim body:{%s}\n",message->body);
 	decode_msg = gaim_base64_decode(message->body,&body_len);
 	date =	(char *)g_hash_table_lookup(message->attr_table, "Date");
@@ -463,8 +469,8 @@
 /* Parse the XML data,
  * prepare to report the OIM to user
  */
-void
-msn_oim_get_process(MsnOim *oim,char *oim_msg)
+static void
+msn_oim_get_process(MsnOim *oim, char *oim_msg)
 {
 	xmlnode *oimNode,*bodyNode,*responseNode,*msgNode;
 	char *msg_data,*msg_str;
@@ -569,7 +575,7 @@
 }
 
 /*msn oim retrieve server connect init */
-void
+static void
 msn_oim_retrieve_connect_init(MsnSoapConn *soapconn)
 {
 	gaim_debug_info("MaYuan","msn_oim_connect...\n");
@@ -579,7 +585,8 @@
 }
 
 /*Msn OIM Send Server Connect Init Function*/
-void msn_oim_send_connect_init(MsnSoapConn *sendconn)
+static void
+msn_oim_send_connect_init(MsnSoapConn *sendconn)
 {
 	gaim_debug_info("MaYuan","msn oim send connect init...\n");
 	msn_soap_init(sendconn,MSN_OIM_SEND_HOST,1,
--- a/libgaim/protocols/msn/oim.h	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/oim.h	Sun Apr 15 03:04:05 2007 +0000
@@ -132,9 +132,9 @@
 void msn_parse_oim_msg(MsnOim *oim,const char *xmlmsg);
 
 /*Send OIM Message*/
-void msn_oim_prep_send_msg_info(MsnOim *oim,
-					char *membername,char*friendname,char *tomember,
-					char * msg);
+void msn_oim_prep_send_msg_info(MsnOim *oim, const char *membername,
+								const char *friendname, const char *tomember,
+								const char * msg);
 
 void msn_oim_send_msg(MsnOim *oim);
 
--- a/libgaim/protocols/msn/slp.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/slp.c	Sun Apr 15 03:04:05 2007 +0000
@@ -341,31 +341,33 @@
 
 		xfer = gaim_xfer_new(account, GAIM_XFER_RECEIVE,
 							 slpcall->slplink->remote_user);
-
-		bin = (char *)gaim_base64_decode(context, &bin_len);
-		file_size = GUINT32_FROM_LE(*((gsize *)bin + 2));
+		if (xfer)
+		{
+			bin = (char *)gaim_base64_decode(context, &bin_len);
+			file_size = GUINT32_FROM_LE(*((gsize *)bin + 2));
 
-		uni_name = (gunichar2 *)(bin + 20);
-		while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) {
-			*uni_name = GUINT16_FROM_LE(*uni_name);
-			uni_name++;
-		}
+			uni_name = (gunichar2 *)(bin + 20);
+			while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) {
+				*uni_name = GUINT16_FROM_LE(*uni_name);
+				uni_name++;
+			}
 
-		file_name = g_utf16_to_utf8((const gunichar2 *)(bin + 20), -1,
-									NULL, NULL, NULL);
+			file_name = g_utf16_to_utf8((const gunichar2 *)(bin + 20), -1,
+										NULL, NULL, NULL);
 
-		g_free(bin);
+			g_free(bin);
 
-		gaim_xfer_set_filename(xfer, file_name);
-		gaim_xfer_set_size(xfer, file_size);
-		gaim_xfer_set_init_fnc(xfer, msn_xfer_init);
-		gaim_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel);
-		gaim_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel);
+			gaim_xfer_set_filename(xfer, file_name);
+			gaim_xfer_set_size(xfer, file_size);
+			gaim_xfer_set_init_fnc(xfer, msn_xfer_init);
+			gaim_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel);
+			gaim_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel);
 
-		slpcall->xfer = xfer;
-		xfer->data = slpcall;
+			slpcall->xfer = xfer;
+			xfer->data = slpcall;
 
-		gaim_xfer_request(xfer);
+			gaim_xfer_request(xfer);
+		}
 	}
 }
 
--- a/libgaim/protocols/msn/slpcall.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/slpcall.c	Sun Apr 15 03:04:05 2007 +0000
@@ -22,7 +22,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include "msn.h"
-#include "msn-utils.h"
+#include "msnutils.h"
 #include "slpcall.h"
 #include "slpsession.h"
 
--- a/libgaim/protocols/msn/soap.h	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/soap.h	Sun Apr 15 03:04:05 2007 +0000
@@ -106,10 +106,11 @@
 
 /*Function Prototype*/
 /*Soap Request Function */
-MsnSoapReq *
-msn_soap_request_new(const char *host,const char *post_url,const char *soap_action,
-				const char *body,
-				GaimInputFunction read_cb,GaimInputFunction written_cb);
+MsnSoapReq *msn_soap_request_new(const char *host, const char *post_url,
+								 const char *soap_action, const char *body,
+								 GaimInputFunction read_cb,
+								 GaimInputFunction written_cb);
+
 void msn_soap_request_free(MsnSoapReq *request);
 void msn_soap_post_request(MsnSoapConn *soapconn,MsnSoapReq *request);
 void msn_soap_post_head_request(MsnSoapConn *soapconn);
--- a/libgaim/protocols/msn/state.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/state.c	Sun Apr 15 03:04:05 2007 +0000
@@ -39,7 +39,8 @@
 };
 
 /* Local Function Prototype*/
-char * msn_build_psm(char * psmstr,char *mediastr,char * guidstr);
+static char *msn_build_psm(const char *psmstr,const char *mediastr,
+						   const char *guidstr);
 
 /*
  * WLM media PSM info build prcedure
@@ -49,8 +50,8 @@
  *	<CurrentMedia>\0Games\01\0Playing {0}\0Game Name\0</CurrentMedia>\
  *	<CurrentMedia>\0Office\01\0Office Message\0Office App Name\0</CurrentMedia>"
  */
-char *
-msn_build_psm(char * psmstr,char *mediastr,char * guidstr)
+static char *
+msn_build_psm(const char *psmstr,const char *mediastr, const char *guidstr)
 {
 	xmlnode *dataNode,*psmNode,*mediaNode,*guidNode;
 	char *result;
@@ -81,11 +82,11 @@
 }
 
 /*get the PSM info from the XML string*/
-const char *
-msn_get_psm(char *xml_str,gsize len)
+char *
+msn_get_psm(char *xml_str, gsize len)
 {
 	xmlnode *payloadNode, *psmNode;
-	char *psm_str,*psm;
+	char *psm_str, *psm;
 	
 	gaim_debug_info("Ma Yuan","msn get PSM\n");
 	payloadNode = xmlnode_from_str(xml_str, len);
@@ -119,7 +120,8 @@
 	GaimStatus *status;
 	MsnCmdProc *cmdproc;
 	MsnTransaction *trans;
-	char *payload,*statusline;
+	char *payload;
+	const char *statusline;
 
 	g_return_if_fail(session != NULL);
 	g_return_if_fail(session->notification != NULL);
@@ -133,7 +135,7 @@
 	presence = gaim_account_get_presence(account);
 	status = gaim_presence_get_active_status(presence);
 	statusline = gaim_status_get_attr_string(status, "message");
-	session ->psm = g_strdup(msn_build_psm(statusline,NULL,NULL));
+	session ->psm = msn_build_psm(statusline, NULL, NULL);
 	payload = session->psm;
 
 	gaim_debug_info("MaYuan","UUX{%s}\n",payload);
--- a/libgaim/protocols/msn/state.h	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/state.h	Sun Apr 15 03:04:05 2007 +0000
@@ -62,7 +62,7 @@
 void msn_set_psm(MsnSession *session);
 
 /*get the PSM info from the XML string*/
-const char * msn_get_psm(char *xml_str,gsize len);
+char * msn_get_psm(char *xml_str,gsize len);
 
 MsnAwayType msn_state_from_account(GaimAccount *account);
 
--- a/libgaim/protocols/msn/switchboard.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/switchboard.c	Sun Apr 15 03:04:05 2007 +0000
@@ -25,7 +25,7 @@
 #include "prefs.h"
 #include "switchboard.h"
 #include "notification.h"
-#include "msn-utils.h"
+#include "msnutils.h"
 
 #include "error.h"
 
@@ -646,6 +646,10 @@
 	swboard = cmdproc->data;
 	user = cmd->params[0];
 
+	/* cmdproc->data is set to NULL when the switchboard is destroyed;
+	 * we may get a bye shortly thereafter. */
+	g_return_if_fail(swboard != NULL);
+
 	if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL))
 		gaim_debug_error("msn_switchboard", "bye_cmd: helper bug\n");
 
--- a/libgaim/protocols/msn/sync.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/sync.c	Sun Apr 15 03:04:05 2007 +0000
@@ -86,10 +86,9 @@
 lsg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
 	MsnSession *session = cmdproc->session;
-	const char *name;
-	int group_id;
+	const char *name, *group_id;
 
-	group_id = atoi(cmd->params[0]);
+	group_id = cmd->params[0];
 	name = gaim_url_decode(cmd->params[1]);
 
 	msn_group_new(session->userlist, group_id, name);
--- a/libgaim/protocols/msn/user.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/user.c	Sun Apr 15 03:04:05 2007 +0000
@@ -90,7 +90,7 @@
 	account = user->userlist->session->account;
 
 	if (user->statusline != NULL) {
-		char *status = g_strdup_printf("%s - %s", user->status, user->statusline);
+		//char *status = g_strdup_printf("%s - %s", user->status, user->statusline);
 		gaim_prpl_got_user_status(account, user->passport, user->status, "message", user->statusline, NULL);
 	}
 	else if (user->status != NULL) {
@@ -188,7 +188,7 @@
 void
 msn_user_set_op(MsnUser *user,int list_op)
 {
-	g_return_if_fail(list_op != NULL);
+	g_return_if_fail(list_op != 0);
 	user->list_op |= list_op;
 }
 
@@ -277,14 +277,14 @@
 	GaimBuddy *b;
 	GaimGroup *g;
 	const char *passport;
-	const char *group_id;
+	char *group_id;
 	const char *group_name;
 
 	g_return_if_fail(user != NULL);
 	g_return_if_fail(id != NULL);
 
 	group_id = g_strdup(id);
-	user->group_ids = g_list_append(user->group_ids,group_id);
+	user->group_ids = g_list_append(user->group_ids, group_id);
 
 	userlist = user->userlist;
 	account = userlist->session->account;
@@ -337,7 +337,8 @@
 	g_return_if_fail(id != NULL);
 
 	user->group_ids = g_list_remove(user->group_ids, id);
-	g_free(id);
+	/* khc need to use g_list_find_custom here to find the right link */
+	//g_free(id);
 }
 
 void
--- a/libgaim/protocols/msn/user.h	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/user.h	Sun Apr 15 03:04:05 2007 +0000
@@ -48,7 +48,7 @@
 	char * uid;				/*< User Id							*/
 
 	const char *status;     /**< The state of the user.         */
-	const char *statusline;	/**< The state of the user.	*/	
+	char *statusline;	    /**< The state of the user.	*/	
 
 	gboolean idle;          /**< The idle state of the user.    */
 
--- a/libgaim/protocols/msn/userlist.c	Sun Apr 15 02:42:11 2007 +0000
+++ b/libgaim/protocols/msn/userlist.c	Sun Apr 15 03:04:05 2007 +0000
@@ -758,7 +758,8 @@
 				{
 					user = msn_userlist_find_add_user(session->userlist,
 						b->name,NULL);
-					msn_user_set_op(user,MSN_LIST_FL_OP);
+					b->proto_data = user;
+					msn_user_set_op(user, MSN_LIST_FL_OP);
 				}
 			}
 		}
@@ -767,13 +768,13 @@
 	{
 		user = msn_userlist_find_add_user(session->userlist,
 						(char *)l->data,NULL);
-		msn_user_set_op(user,MSN_LIST_AL_OP);
+		msn_user_set_op(user, MSN_LIST_AL_OP);
 	}
 	for (l = session->account->deny; l != NULL; l = l->next)
 	{
 		user = msn_userlist_find_add_user(session->userlist,
 						(char *)l->data,NULL);
-		msn_user_set_op(user,MSN_LIST_BL_OP);
+		msn_user_set_op(user, MSN_LIST_BL_OP);
 	}
 }