diff options
| -rw-r--r-- | lib/xmltree.c | 14 | ||||
| -rw-r--r-- | protocols/msn/msn.c | 37 | ||||
| -rw-r--r-- | protocols/msn/msn.h | 1 | ||||
| -rw-r--r-- | protocols/msn/msn_util.c | 49 | ||||
| -rw-r--r-- | protocols/msn/ns.c | 80 | ||||
| -rw-r--r-- | protocols/msn/soap.c | 34 | ||||
| -rw-r--r-- | protocols/msn/soap.h | 33 | ||||
| -rw-r--r-- | protocols/nogaim.h | 2 | ||||
| -rw-r--r-- | storage_xml.c | 10 | 
9 files changed, 113 insertions, 147 deletions
| diff --git a/lib/xmltree.c b/lib/xmltree.c index f413b8f7..5fd43014 100644 --- a/lib/xmltree.c +++ b/lib/xmltree.c @@ -173,20 +173,20 @@ int xt_handle( struct xt_parser *xt, struct xt_node *node, int depth )  	if( node->flags & XT_COMPLETE && !( node->flags & XT_SEEN ) )  	{ -		for( i = 0; xt->handlers[i].func; i ++ ) +		if( xt->handlers ) for( i = 0; xt->handlers[i].func; i ++ )  		{  			/* This one is fun! \o/ */ -						/* If handler.name == NULL it means it should always match. */ +			    /* If handler.name == NULL it means it should always match. */  			if( ( xt->handlers[i].name == NULL ||  -						/* If it's not, compare. There should always be a name. */ +			      /* If it's not, compare. There should always be a name. */  			      g_strcasecmp( xt->handlers[i].name, node->name ) == 0 ) && -						/* If handler.parent == NULL, it's a match. */ +			    /* If handler.parent == NULL, it's a match. */  			    ( xt->handlers[i].parent == NULL || -						/* If there's a parent node, see if the name matches. */ +			      /* If there's a parent node, see if the name matches. */  			      ( node->parent ? g_strcasecmp( xt->handlers[i].parent, node->parent->name ) == 0 :  -						/* If there's no parent, the handler should mention <root> as a parent. */ -			                       g_strcasecmp( xt->handlers[i].parent, "<root>" ) == 0 ) ) ) +			      /* If there's no parent, the handler should mention <root> as a parent. */ +			                       strcmp( xt->handlers[i].parent, "<root>" ) == 0 ) ) )  			{  				st = xt->handlers[i].func( node, xt->data ); diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index 99db509c..ed0881d1 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -24,6 +24,7 @@  */  #include "nogaim.h" +#include "soap.h"  #include "msn.h"  int msn_chat_id; @@ -34,8 +35,11 @@ static char *set_eval_display_name( set_t *set, char *value );  static void msn_init( account_t *acc )  { -	set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc ); -	set_add( &acc->set, "local_display_name", "false", set_eval_bool, acc ); +	set_t *s; +	 +	s = set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc ); +	s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY; +	  	set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc );  	set_add( &acc->set, "switchboard_keepalives", "false", set_eval_bool, acc ); @@ -202,11 +206,6 @@ static void msn_set_away( struct im_connection *ic, char *state, char *message )  		return;  } -static void msn_set_my_name( struct im_connection *ic, char *info ) -{ -	msn_set_display_name( ic, info ); -} -  static void msn_get_info(struct im_connection *ic, char *who)   {  	/* Just make an URL and let the user fetch the info */ @@ -331,10 +330,9 @@ static char *set_eval_display_name( set_t *set, char *value )  {  	account_t *acc = set->data;  	struct im_connection *ic = acc->ic; -	 -	/* Allow any name if we're offline. */ -	if( ic == NULL ) -		return value; +	struct msn_data *md = ic->proto_data; +	char buf[512]; +	char *fn;  	if( strlen( value ) > 129 )  	{ @@ -342,10 +340,18 @@ static char *set_eval_display_name( set_t *set, char *value )  		return NULL;  	} -	/* Returning NULL would be better, because the server still has to -	   confirm the name change. However, it looks a bit confusing to the -	   user. */ -	return msn_set_display_name( ic, value ) ? value : NULL; +	msn_soap_addressbook_set_display_name( ic, value ); + +	fn = g_malloc( strlen( value ) * 3 + 1 ); +	strcpy( fn, value ); +	http_encode( fn ); +	g_snprintf( buf, sizeof( buf ), "PRP %d MFN %s\r\n", +	            ++md->trId, fn ); +	g_free( fn ); +	 +	/* Note: We don't actually know if the server accepted the new name, +	   and won't give proper feedback yet if it doesn't. */ +	return msn_write( ic, buf, strlen( buf ) ) ? value : NULL;  }  static void msn_buddy_data_add( bee_user_t *bu ) @@ -374,7 +380,6 @@ void msn_initmodule()  	ret->away_states = msn_away_states;  	ret->set_away = msn_set_away;  	ret->get_info = msn_get_info; -	ret->set_my_name = msn_set_my_name;  	ret->add_buddy = msn_add_buddy;  	ret->remove_buddy = msn_remove_buddy;  	ret->chat_msg = msn_chat_msg; diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 5c7949c9..1828cc8a 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -206,7 +206,6 @@ void msn_buddy_ask( struct im_connection *ic, char *handle, char *realname );  char *msn_findheader( char *text, char *header, int len );  char **msn_linesplit( char *line );  int msn_handler( struct msn_handler_data *h ); -char *msn_http_encode( const char *input );  void msn_msgq_purge( struct im_connection *ic, GSList **list );  gboolean msn_set_display_name( struct im_connection *ic, const char *rawname );  char *msn_p11_challenge( char *challenge ); diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c index 3a19d92f..bd1bea42 100644 --- a/protocols/msn/msn_util.c +++ b/protocols/msn/msn_util.c @@ -60,7 +60,7 @@ int msn_logged_in( struct im_connection *ic )  int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *who, const char *realname_, const char *group )  {  	struct msn_data *md = ic->proto_data; -	char buf[1024], *realname, groupid[8]; +	char buf[1024], realname[strlen(realname_)*3+1], groupid[8];  	*groupid = '\0';  	if( group ) @@ -93,9 +93,10 @@ int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *  			if( l == NULL )  			{ -				char *groupname = msn_http_encode( group ); +				char groupname[strlen(group)+1]; +				strcpy( groupname, group ); +				http_encode( groupname );  				g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 ); -				g_free( groupname );  				return msn_write( ic, buf, strlen( buf ) );  			}  			else @@ -108,9 +109,9 @@ int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *  		}  	} -	realname = msn_http_encode( realname_ ); +	strcpy( realname, realname_ ); +	http_encode( realname );  	g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s%s\r\n", ++md->trId, list, who, realname, groupid ); -	g_free( realname );  	return msn_write( ic, buf, strlen( buf ) );  } @@ -379,32 +380,6 @@ int msn_handler( struct msn_handler_data *h )  	return( 1 );  } -/* The difference between this function and the normal http_encode() function -   is that this one escapes every 7-bit ASCII character because this is said -   to avoid some lame server-side checks when setting a real-name. Also, -   non-ASCII characters are not escaped because MSN servers don't seem to -   appreciate that! */ -char *msn_http_encode( const char *input ) -{ -	char *ret, *s; -	int i; -	 -	ret = s = g_new0( char, strlen( input ) * 3 + 1 ); -	for( i = 0; input[i]; i ++ ) -		if( input[i] & 128 ) -		{ -			*s = input[i]; -			s ++; -		} -		else -		{ -			g_snprintf( s, 4, "%%%02X", input[i] ); -			s += 3; -		} -	 -	return ret; -} -  void msn_msgq_purge( struct im_connection *ic, GSList **list )  {  	struct msn_message *m; @@ -445,18 +420,6 @@ void msn_msgq_purge( struct im_connection *ic, GSList **list )  	g_string_free( ret, TRUE );  } -gboolean msn_set_display_name( struct im_connection *ic, const char *rawname ) -{ -	char *fn = msn_http_encode( rawname ); -	struct msn_data *md = ic->proto_data; -	char buf[1024]; -	 -	g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn ); -	g_free( fn ); -	 -	return msn_write( ic, buf, strlen( buf ) ) != 0; -} -  /* Copied and heavily modified from http://tmsnc.sourceforge.net/chl.c */  char *msn_p11_challenge( char *challenge )  { diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index 0c067b8c..777a6ebd 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -34,7 +34,6 @@ static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition c  static int msn_ns_command( gpointer data, char **cmd, int num_parts );  static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts ); -static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name );  static void msn_ns_send_adl( struct im_connection *ic );  gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ) @@ -473,40 +472,6 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts )  		imc_logout( ic, allow_reconnect );  		return( 0 );  	} -#if 0 -	/* Discard this one completely for now since I don't care about the ack -	   and since MSN servers can apparently screw up the formatting. */ -	else if( strcmp( cmd[0], "REA" ) == 0 ) -	{ -		if( num_parts < 5 ) -		{ -			imcb_error( ic, "Syntax error" ); -			imc_logout( ic, TRUE ); -			return( 0 ); -		} -		 -		if( g_strcasecmp( cmd[3], ic->acc->user ) == 0 ) -		{ -			set_t *s; -			 -			http_decode( cmd[4] ); -			strncpy( ic->displayname, cmd[4], sizeof( ic->displayname ) ); -			ic->displayname[sizeof(ic->displayname)-1] = 0; -			 -			if( ( s = set_find( &ic->acc->set, "display_name" ) ) ) -			{ -				g_free( s->value ); -				s->value = g_strdup( cmd[4] ); -			} -		} -		else -		{ -			/* This is not supposed to happen, but let's handle it anyway... */ -			http_decode( cmd[4] ); -			imcb_rename_buddy( ic, cmd[3], cmd[4] ); -		} -	} -#endif  	else if( strcmp( cmd[0], "IPG" ) == 0 )  	{  		imcb_error( ic, "Received IPG command, we don't handle them yet." ); @@ -800,48 +765,3 @@ static void msn_ns_send_adl( struct im_connection *ic )  	g_free( adls );  	xt_free_node( adl );  } - -static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name ) -{ -	set_t *s; -	 -	if( ( s = set_find( &ic->acc->set, "display_name" ) ) == NULL ) -		return FALSE; /* Shouldn't happen.. */ -	 -	http_decode( name ); -	 -	if( s->value && strcmp( s->value, name ) == 0 ) -	{ -		return TRUE; -		/* The names match, nothing to worry about. */ -	} -	else if( s->value != NULL && -	         ( strcmp( name, ic->acc->user ) == 0 || -	           set_getbool( &ic->acc->set, "local_display_name" ) ) ) -	{ -		/* The server thinks our display name is our e-mail address -		   which is probably wrong, or the user *wants* us to do this: -		   Always use the locally set display_name. */ -		return msn_set_display_name( ic, s->value ); -	} -	else -	{ -		if( s->value && *s->value ) -			imcb_log( ic, "BitlBee thinks your display name is `%s' but " -			              "the MSN server says it's `%s'. Using the MSN " -			              "server's name. Set local_display_name to true " -			              "to use the local name.", s->value, name ); -		 -		if( g_utf8_validate( name, -1, NULL ) ) -		{ -			g_free( s->value ); -			s->value = g_strdup( name ); -		} -		else -		{ -			imcb_log( ic, "Warning: Friendly name in server response was corrupted" ); -		} -		 -		return TRUE; -	} -} diff --git a/protocols/msn/soap.c b/protocols/msn/soap.c index 5eae3089..cd54858f 100644 --- a/protocols/msn/soap.c +++ b/protocols/msn/soap.c @@ -608,3 +608,37 @@ int msn_soap_addressbook_request( struct im_connection *ic )  	                                 msn_soap_addressbook_handle_response,  	                                 msn_soap_addressbook_free_data );  } + +/* Variant: Change our display name. */ +static int msn_soap_ab_namechange_build_request( struct msn_soap_req_data *soap_req ) +{ +	struct msn_data *md = soap_req->ic->proto_data; +	 +	soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL ); +	soap_req->action = g_strdup( SOAP_AB_NAMECHANGE_ACTION ); +	soap_req->payload = g_markup_printf_escaped( SOAP_AB_NAMECHANGE_PAYLOAD, +		md->tokens[1], (char *) soap_req->data ); +	 +	return 1; +} + +static int msn_soap_ab_namechange_handle_response( struct msn_soap_req_data *soap_req ) +{ +	/* TODO: Ack the change? Not sure what the NAKs look like.. */ +	return MSN_SOAP_OK; +} + +static int msn_soap_ab_namechange_free_data( struct msn_soap_req_data *soap_req ) +{ +	g_free( soap_req->data ); +	return 0; +} + +int msn_soap_addressbook_set_display_name( struct im_connection *ic, const char *new ) +{ +	return msn_soap_start( ic, g_strdup( new ), +	                       msn_soap_ab_namechange_build_request, +	                       NULL, +	                       msn_soap_ab_namechange_handle_response, +	                       msn_soap_ab_namechange_free_data ); +} diff --git a/protocols/msn/soap.h b/protocols/msn/soap.h index 14b0624b..5673583a 100644 --- a/protocols/msn/soap.h +++ b/protocols/msn/soap.h @@ -219,7 +219,40 @@ int msn_soap_memlist_request( struct im_connection *ic );    "</soap:Body>" \  "</soap:Envelope>" +#define SOAP_AB_NAMECHANGE_ACTION "http://www.msn.com/webservices/AddressBook/ABContactUpdate" + +#define SOAP_AB_NAMECHANGE_PAYLOAD \ +"<?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>CFE80F9D-180F-4399-82AB-413F33A1FA11</ApplicationId>" \ +      "<IsMigration>false</IsMigration>" \ +      "<PartnerScenario>Initial</PartnerScenario>" \ +    "</ABApplicationHeader>" \ +    "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ +      "<ManagedGroupRequest>false</ManagedGroupRequest>" \ +      "<TicketToken>%s</TicketToken>" \ +    "</ABAuthHeader>" \ +  "</soap:Header>" \ +    "<soap:Body>" \ +        "<ABContactUpdate xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ +            "<abId>00000000-0000-0000-0000-000000000000</abId>" \ +            "<contacts>" \ +                "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ +                    "<contactInfo>" \ +                        "<contactType>Me</contactType>" \ +                        "<displayName>%s</displayName>" \ +                    "</contactInfo>" \ +                    "<propertiesChanged>DisplayName</propertiesChanged>" \ +                "</Contact>" \ +            "</contacts>" \ +        "</ABContactUpdate>" \ +    "</soap:Body>" \ +"</soap:Envelope>" +  int msn_soap_addressbook_request( struct im_connection *ic ); +int msn_soap_addressbook_set_display_name( struct im_connection *ic, const char *new );  #endif /* __SOAP_H__ */ diff --git a/protocols/nogaim.h b/protocols/nogaim.h index be67bb24..90254508 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -193,6 +193,8 @@ struct prpl {  	/* Request profile info. Free-formatted stuff, the IM module gives back  	   this info via imcb_log(). Implementing these are optional. */  	void (* get_info)	(struct im_connection *, char *who); +	/* set_my_name is *DEPRECATED*, not used by the UI anymore. Use the +	   display_name setting instead. */  	void (* set_my_name)	(struct im_connection *, char *name);  	void (* set_name)	(struct im_connection *, char *who, char *name); diff --git a/storage_xml.c b/storage_xml.c index 1d6757ae..5035e214 100644 --- a/storage_xml.c +++ b/storage_xml.c @@ -319,6 +319,16 @@ static void xml_text( GMarkupParseContext *ctx, const gchar *text_orig, gsize te  	}  	else if( g_strcasecmp( g_markup_parse_context_get_element( ctx ), "setting" ) == 0 && xd->current_setting )  	{ +		if( xd->current_account ) +		{ +			set_t *s = set_find( xd->current_set_head, xd->current_setting ); +			if( s && ( s->flags & ACC_SET_ONLINE_ONLY ) ) +			{ +				g_free( xd->current_setting ); +				xd->current_setting = NULL; +				return; +			} +		}  		set_setstr( xd->current_set_head, xd->current_setting, (char*) text );  		g_free( xd->current_setting );  		xd->current_setting = NULL; | 
