Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision c6ca3ee33e27feefb8cae0dc1d55a7239baf43cb)
+++ protocols/msn/msn.c	(revision fb009891bb60921401ffeb47b33cf35a246cbe34)
@@ -117,5 +117,4 @@
 {
 	struct msn_switchboard *sb;
-	struct msn_data *md = ic->proto_data;
 	
 	if( ( sb = msn_sb_by_handle( ic, who ) ) )
@@ -126,5 +125,4 @@
 	{
 		struct msn_message *m;
-		char buf[1024];
 		
 		/* Create a message. We have to arrange a usable switchboard, and send the message later. */
@@ -133,38 +131,5 @@
 		m->text = g_strdup( message );
 		
-		/* FIXME: *CHECK* the reliability of using spare sb's! */
-		if( ( sb = msn_sb_spare( ic ) ) )
-		{
-			debug( "Trying to use a spare switchboard to message %s", who );
-			
-			sb->who = g_strdup( who );
-			g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, who );
-			if( msn_sb_write( sb, buf, strlen( buf ) ) )
-			{
-				/* He/She should join the switchboard soon, let's queue the message. */
-				sb->msgq = g_slist_append( sb->msgq, m );
-				return( 1 );
-			}
-		}
-		
-		debug( "Creating a new switchboard to message %s", who );
-		
-		/* If we reach this line, there was no spare switchboard, so let's make one. */
-		g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
-		if( !msn_write( ic, buf, strlen( buf ) ) )
-		{
-			g_free( m->who );
-			g_free( m->text );
-			g_free( m );
-			
-			return( 0 );
-		}
-		
-		/* And queue the message to md. We'll pick it up when the switchboard comes up. */
-		md->msgq = g_slist_append( md->msgq, m );
-		
-		/* FIXME: If the switchboard creation fails, the message will not be sent. */
-		
-		return( 1 );
+		return msn_sb_write_msg( ic, m );
 	}
 	
@@ -178,6 +143,7 @@
 	
 	if( l == NULL )
-		for( i = 0; msn_away_state_list[i].number > -1; i ++ )
-			l = g_list_append( l, (void*) msn_away_state_list[i].name );
+		for( i = 0; *msn_away_state_list[i].code; i ++ )
+			if( *msn_away_state_list[i].name )
+				l = g_list_append( l, (void*) msn_away_state_list[i].name );
 	
 	return l;
@@ -188,15 +154,12 @@
 	char buf[1024];
 	struct msn_data *md = ic->proto_data;
-	const struct msn_away_state *st;
-	
-	if( strcmp( state, GAIM_AWAY_CUSTOM ) == 0 )
-		st = msn_away_state_by_name( "Away" );
+	
+	if( state )
+		md->away_state = msn_away_state_by_name( state ) ? :
+		                 msn_away_state_list + 1;
 	else
-		st = msn_away_state_by_name( state );
-	
-	if( !st ) st = msn_away_state_list;
-	md->away_state = st;
-	
-	g_snprintf( buf, sizeof( buf ), "CHG %d %s\r\n", ++md->trId, st->code );
+		md->away_state = msn_away_state_list;
+	
+	g_snprintf( buf, sizeof( buf ), "CHG %d %s\r\n", ++md->trId, md->away_state->code );
 	msn_write( ic, buf, strlen( buf ) );
 }
@@ -256,6 +219,4 @@
 {
 	struct msn_switchboard *sb;
-	struct msn_data *md = ic->proto_data;
-	char buf[1024];
 	
 	if( ( sb = msn_sb_by_handle( ic, who ) ) )
@@ -267,20 +228,4 @@
 	{
 		struct msn_message *m;
-		
-		if( ( sb = msn_sb_spare( ic ) ) )
-		{
-			debug( "Trying to reuse an existing switchboard as a groupchat with %s", who );
-			g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, who );
-			if( msn_sb_write( sb, buf, strlen( buf ) ) )
-				return msn_sb_to_chat( sb );
-		}
-		
-		/* If the stuff above failed for some reason: */
-		debug( "Creating a new switchboard to groupchat with %s", who );
-		
-		/* Request a new switchboard. */
-		g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
-		if( !msn_write( ic, buf, strlen( buf ) ) )
-			return( 0 );
 		
 		/* Create a magic message. This is quite hackish, but who cares? :-P */
@@ -289,8 +234,6 @@
 		m->text = g_strdup( GROUPCHAT_SWITCHBOARD_MESSAGE );
 		
-		/* Queue the magic message and cross your fingers. */
-		md->msgq = g_slist_append( md->msgq, m );
-		
-		/* FIXME: Can I try to return something here already? */
+		msn_sb_write_msg( ic, m );
+
 		return NULL;
 	}
Index: protocols/msn/msn.h
===================================================================
--- protocols/msn/msn.h	(revision c6ca3ee33e27feefb8cae0dc1d55a7239baf43cb)
+++ protocols/msn/msn.h	(revision fb009891bb60921401ffeb47b33cf35a246cbe34)
@@ -23,4 +23,7 @@
   Suite 330, Boston, MA  02111-1307  USA
 */
+
+#ifndef _MSN_H
+#define _MSN_H
 
 /* Some hackish magicstrings to make special-purpose messages/switchboards.
@@ -94,5 +97,4 @@
 struct msn_away_state
 {
-	int number;
 	char code[4];
 	char name[16];
@@ -176,2 +178,5 @@
 void msn_sb_destroy( struct msn_switchboard *sb );
 gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond );
+int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m );
+
+#endif //_MSN_H
Index: protocols/msn/msn_util.c
===================================================================
--- protocols/msn/msn_util.c	(revision c6ca3ee33e27feefb8cae0dc1d55a7239baf43cb)
+++ protocols/msn/msn_util.c	(revision fb009891bb60921401ffeb47b33cf35a246cbe34)
@@ -171,7 +171,7 @@
 		
 		/* End of headers? */
-		if( strncmp( text + i - 2, "\n\n", 2 ) == 0 ||
-		    strncmp( text + i - 4, "\r\n\r\n", 4 ) == 0 ||
-		    strncmp( text + i - 2, "\r\r", 2 ) == 0 )
+		if( ( i >= 4 && strncmp( text + i - 4, "\r\n\r\n", 4 ) == 0 ) ||
+		    ( i >= 2 && ( strncmp( text + i - 2, "\n\n", 2 ) == 0 ||   
+		                  strncmp( text + i - 2, "\r\r", 2 ) == 0 ) ) )
 		{
 			break;
@@ -374,5 +374,5 @@
 	*list = NULL;
 	
-	imcb_log( ic, ret->str );
+	imcb_log( ic, "%s", ret->str );
 	g_string_free( ret, TRUE );
 }
Index: protocols/msn/ns.c
===================================================================
--- protocols/msn/ns.c	(revision c6ca3ee33e27feefb8cae0dc1d55a7239baf43cb)
+++ protocols/msn/ns.c	(revision fb009891bb60921401ffeb47b33cf35a246cbe34)
@@ -420,9 +420,10 @@
 		{
 			/* FIXME: Warn/Bomb about unknown away state? */
-			st = msn_away_state_list;
-		}
-		
-		imcb_buddy_status( ic, cmd[3], OPT_LOGGED_IN |
-		                   ( st->number ? OPT_AWAY : 0 ), st->name, NULL );
+			st = msn_away_state_list + 1;
+		}
+		
+		imcb_buddy_status( ic, cmd[3], OPT_LOGGED_IN | 
+		                   ( st != msn_away_state_list ? OPT_AWAY : 0 ),
+		                   st->name, NULL );
 	}
 	else if( strcmp( cmd[0], "FLN" ) == 0 )
@@ -449,9 +450,10 @@
 		{
 			/* FIXME: Warn/Bomb about unknown away state? */
-			st = msn_away_state_list;
-		}
-		
-		imcb_buddy_status( ic, cmd[2], OPT_LOGGED_IN |
-		                   ( st->number ? OPT_AWAY : 0 ), st->name, NULL );
+			st = msn_away_state_list + 1;
+		}
+		
+		imcb_buddy_status( ic, cmd[2], OPT_LOGGED_IN | 
+		                   ( st != msn_away_state_list ? OPT_AWAY : 0 ),
+		                   st->name, NULL );
 	}
 	else if( strcmp( cmd[0], "RNG" ) == 0 )
@@ -663,6 +665,6 @@
 				}
 				
-				if( arg1 ) g_free( arg1 );
-				if( mtype ) g_free( mtype );
+				g_free( arg1 );
+				g_free( mtype );
 			}
 			else if( g_strncasecmp( ct, "text/x-msmsgsprofile", 20 ) == 0 )
@@ -672,23 +674,28 @@
 			else if( g_strncasecmp( ct, "text/x-msmsgsinitialemailnotification", 37 ) == 0 )
 			{
-				char *inbox = msn_findheader( body, "Inbox-Unread:", blen );
-				char *folders = msn_findheader( body, "Folders-Unread:", blen );
-				
-				if( inbox && folders && set_getbool( &ic->acc->set, "mail_notifications" ) )
+				if( set_getbool( &ic->acc->set, "mail_notifications" ) )
 				{
-					imcb_log( ic, "INBOX contains %s new messages, plus %s messages in other folders.", inbox, folders );
+					char *inbox = msn_findheader( body, "Inbox-Unread:", blen );
+					char *folders = msn_findheader( body, "Folders-Unread:", blen );
+
+					if( inbox && folders )
+						imcb_log( ic, "INBOX contains %s new messages, plus %s messages in other folders.", inbox, folders );
+					
+					g_free( inbox );
+					g_free( folders );
 				}
-				
-				g_free( inbox );
-				g_free( folders );
 			}
 			else if( g_strncasecmp( ct, "text/x-msmsgsemailnotification", 30 ) == 0 )
 			{
-				char *from = msn_findheader( body, "From-Addr:", blen );
-				char *fromname = msn_findheader( body, "From:", blen );
-				
-				if( from && fromname && set_getbool( &ic->acc->set, "mail_notifications" ) )
+				if( set_getbool( &ic->acc->set, "mail_notifications" ) )
 				{
-					imcb_log( ic, "Received an e-mail message from %s <%s>.", fromname, from );
+					char *from = msn_findheader( body, "From-Addr:", blen );
+					char *fromname = msn_findheader( body, "From:", blen );
+					
+					if( from && fromname )
+						imcb_log( ic, "Received an e-mail message from %s <%s>.", fromname, from );
+
+					g_free( from );
+					g_free( fromname );
 				}
 			}
Index: protocols/msn/sb.c
===================================================================
--- protocols/msn/sb.c	(revision c6ca3ee33e27feefb8cae0dc1d55a7239baf43cb)
+++ protocols/msn/sb.c	(revision fb009891bb60921401ffeb47b33cf35a246cbe34)
@@ -44,4 +44,46 @@
 		return( 0 );
 	}
+	
+	return( 1 );
+}
+
+int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m )
+{
+	struct msn_data *md = ic->proto_data;
+	struct msn_switchboard *sb;
+	char buf[1024];
+
+	/* FIXME: *CHECK* the reliability of using spare sb's! */
+	if( ( sb = msn_sb_spare( ic ) ) )
+	{
+		debug( "Trying to use a spare switchboard to message %s", m->who );
+		
+		sb->who = g_strdup( m->who );
+		g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, m->who );
+		if( msn_sb_write( sb, buf, strlen( buf ) ) )
+		{
+			/* He/She should join the switchboard soon, let's queue the message. */
+			sb->msgq = g_slist_append( sb->msgq, m );
+			return( 1 );
+		}
+	}
+	
+	debug( "Creating a new switchboard to message %s", m->who );
+	
+	/* If we reach this line, there was no spare switchboard, so let's make one. */
+	g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
+	if( !msn_write( ic, buf, strlen( buf ) ) )
+	{
+		g_free( m->who );
+		g_free( m->text );
+		g_free( m );
+		
+		return( 0 );
+	}
+	
+	/* And queue the message to md. We'll pick it up when the switchboard comes up. */
+	md->msgq = g_slist_append( md->msgq, m );
+	
+	/* FIXME: If the switchboard creation fails, the message will not be sent. */
 	
 	return( 1 );
Index: protocols/msn/tables.c
===================================================================
--- protocols/msn/tables.c	(revision c6ca3ee33e27feefb8cae0dc1d55a7239baf43cb)
+++ protocols/msn/tables.c	(revision fb009891bb60921401ffeb47b33cf35a246cbe34)
@@ -29,25 +29,14 @@
 const struct msn_away_state msn_away_state_list[] =
 {
-	{  0, "NLN", "Available" },
-	{  1, "BSY", "Busy" },
-	{  3, "IDL", "Idle" },
-	{  5, "BRB", "Be Right Back" },
-	{  7, "AWY", "Away" },
-	{  9, "PHN", "On the Phone" },
-	{ 11, "LUN", "Out to Lunch" },
-	{ 13, "HDN", "Hidden" },
-	{ -1, "",    "" }
+	{ "NLN", "" },
+	{ "AWY", "Away" },
+	{ "BSY", "Busy" },
+	{ "IDL", "Idle" },
+	{ "BRB", "Be Right Back" },
+	{ "PHN", "On the Phone" },
+	{ "LUN", "Out to Lunch" },
+	{ "HDN", "Hidden" },
+	{ "",    "" }
 };
-
-const struct msn_away_state *msn_away_state_by_number( int number )
-{
-	int i;
-	
-	for( i = 0; msn_away_state_list[i].number > -1; i ++ )
-		if( msn_away_state_list[i].number == number )
-			return( msn_away_state_list + i );
-	
-	return( NULL );
-}
 
 const struct msn_away_state *msn_away_state_by_code( char *code )
@@ -55,9 +44,9 @@
 	int i;
 	
-	for( i = 0; msn_away_state_list[i].number > -1; i ++ )
+	for( i = 0; *msn_away_state_list[i].code; i ++ )
 		if( g_strcasecmp( msn_away_state_list[i].code, code ) == 0 )
 			return( msn_away_state_list + i );
 	
-	return( NULL );
+	return NULL;
 }
 
@@ -66,9 +55,9 @@
 	int i;
 	
-	for( i = 0; msn_away_state_list[i].number > -1; i ++ )
+	for( i = 0; *msn_away_state_list[i].code; i ++ )
 		if( g_strcasecmp( msn_away_state_list[i].name, name ) == 0 )
 			return( msn_away_state_list + i );
 	
-	return( NULL );
+	return NULL;
 }
 
