diff options
| -rw-r--r-- | protocols/msn/msn_util.c | 15 | ||||
| -rw-r--r-- | protocols/msn/soap.c | 86 | ||||
| -rw-r--r-- | protocols/msn/soap.h | 37 | ||||
| -rw-r--r-- | protocols/msn/tables.c | 2 | 
4 files changed, 135 insertions, 5 deletions
| diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c index b7fdda28..84d68b8c 100644 --- a/protocols/msn/msn_util.c +++ b/protocols/msn/msn_util.c @@ -73,7 +73,7 @@ static char *adlrml_entry( const char *handle_, msn_buddy_flags_t list )  		domain, handle, list );  } -int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname_, const char *group ) +int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname, const char *group )  {  	struct msn_data *md = ic->proto_data;  	char buf[1024], groupid[8]; @@ -130,13 +130,17 @@ int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const  	}  #endif -	if( !( bu = bee_user_by_handle( ic->bee, ic, who ) ) || +	if( !( ( bu = bee_user_by_handle( ic->bee, ic, who ) ) || +	       ( bu = bee_user_new( ic->bee, ic, who, 0 ) ) ) ||  	    !( bd = bu->data ) || bd->flags & list )  		return 1;  	bd->flags |= list; -	msn_soap_memlist_edit( ic, who, TRUE, list ); +	if( list == MSN_BUDDY_FL ) +		msn_soap_ab_contact_add( ic, bu ); +	else +		msn_soap_memlist_edit( ic, who, TRUE, list );  	if( ( adl = adlrml_entry( who, list ) ) )  	{ @@ -178,7 +182,10 @@ int msn_buddy_list_remove( struct im_connection *ic, msn_buddy_flags_t list, con  	bd->flags &= ~list; -	msn_soap_memlist_edit( ic, who, FALSE, list ); +	if( list == MSN_BUDDY_FL ) +		msn_soap_ab_contact_del( ic, bu ); +	else +		msn_soap_memlist_edit( ic, who, FALSE, list );  	if( ( adl = adlrml_entry( who, list ) ) )  	{ diff --git a/protocols/msn/soap.c b/protocols/msn/soap.c index 130df840..13ef7e37 100644 --- a/protocols/msn/soap.c +++ b/protocols/msn/soap.c @@ -749,3 +749,89 @@ int msn_soap_addressbook_set_display_name( struct im_connection *ic, const char  	                       msn_soap_ab_namechange_handle_response,  	                       msn_soap_ab_namechange_free_data );  } + +/* Add a contact. */ +static int msn_soap_ab_contact_add_build_request( struct msn_soap_req_data *soap_req ) +{ +	struct msn_data *md = soap_req->ic->proto_data; +	bee_user_t *bu = soap_req->data; +	 +	soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL ); +	soap_req->action = g_strdup( SOAP_AB_CONTACT_ADD_ACTION ); +	soap_req->payload = msn_soap_abservice_build( SOAP_AB_CONTACT_ADD_PAYLOAD, +		"ContactSave", md->tokens[1], bu->handle, bu->fullname ? bu->fullname : bu->handle ); +	 +	return 1; +} + +static xt_status msn_soap_ab_contact_add_cid( struct xt_node *node, gpointer data ) +{ +	struct msn_soap_req_data *soap_req = data; +	bee_user_t *bu = soap_req->data; +	struct msn_buddy_data *bd = bu->data; +	 +	g_free( bd->cid ); +	bd->cid = g_strdup( node->text ); +	 +	return XT_HANDLED; +} + +static const struct xt_handler_entry msn_soap_ab_contact_add_parser[] = { +	{ "guid", "ABContactAddResult", msn_soap_ab_contact_add_cid }, +	{ NULL,               NULL,     NULL                        } +}; + +static int msn_soap_ab_contact_add_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_contact_add_free_data( struct msn_soap_req_data *soap_req ) +{ +	return 0; +} + +int msn_soap_ab_contact_add( struct im_connection *ic, bee_user_t *bu ) +{ +	return msn_soap_start( ic, bu, +	                       msn_soap_ab_contact_add_build_request, +	                       msn_soap_ab_contact_add_parser, +	                       msn_soap_ab_contact_add_handle_response, +	                       msn_soap_ab_contact_add_free_data ); +} + +/* Remove a contact. */ +static int msn_soap_ab_contact_del_build_request( struct msn_soap_req_data *soap_req ) +{ +	struct msn_data *md = soap_req->ic->proto_data; +	bee_user_t *bu = soap_req->data; +	struct msn_buddy_data *bd = bu->data; +	 +	soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL ); +	soap_req->action = g_strdup( SOAP_AB_CONTACT_DEL_ACTION ); +	soap_req->payload = msn_soap_abservice_build( SOAP_AB_CONTACT_DEL_PAYLOAD, +		"Timer", md->tokens[1], bd->cid ); +	 +	return 1; +} + +static int msn_soap_ab_contact_del_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_contact_del_free_data( struct msn_soap_req_data *soap_req ) +{ +	return 0; +} + +int msn_soap_ab_contact_del( struct im_connection *ic, bee_user_t *bu ) +{ +	return msn_soap_start( ic, bu, +	                       msn_soap_ab_contact_del_build_request, +	                       NULL, +	                       msn_soap_ab_contact_del_handle_response, +	                       msn_soap_ab_contact_del_free_data ); +} diff --git a/protocols/msn/soap.h b/protocols/msn/soap.h index 8ce893df..19a5c6ae 100644 --- a/protocols/msn/soap.h +++ b/protocols/msn/soap.h @@ -247,8 +247,43 @@ int msn_soap_memlist_edit( struct im_connection *ic, const char *handle, gboolea              "</contacts>" \          "</ABContactUpdate>" +#define SOAP_AB_CONTACT_ADD_ACTION "http://www.msn.com/webservices/AddressBook/ABContactAdd" + +#define SOAP_AB_CONTACT_ADD_PAYLOAD \ +        "<ABContactAdd 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>LivePending</contactType>" \ +                        "<passportName>%s</passportName>" \ +                        "<isMessengerUser>true</isMessengerUser>" \ +                        "<MessengerMemberInfo>" \ +                            "<DisplayName>%s</DisplayName>" \ +                        "</MessengerMemberInfo>" \ +                    "</contactInfo>" \ +                "</Contact>" \ +            "</contacts>" \ +            "<options>" \ +                "<EnableAllowListManagement>true</EnableAllowListManagement>" \ +            "</options>" \ +        "</ABContactAdd>" + +#define SOAP_AB_CONTACT_DEL_ACTION "http://www.msn.com/webservices/AddressBook/ABContactDelete" + +#define SOAP_AB_CONTACT_DEL_PAYLOAD \ +        "<ABContactDelete xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ +            "<abId>00000000-0000-0000-0000-000000000000</abId>" \ +            "<contacts>" \ +                "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ +                    "<contactId>%s</contactId>" \ +                "</Contact>" \ +            "</contacts>" \ +        "</ABContactDelete>" +  int msn_soap_addressbook_request( struct im_connection *ic );  int msn_soap_addressbook_set_display_name( struct im_connection *ic, const char *new ); - +int msn_soap_ab_contact_add( struct im_connection *ic, bee_user_t *bu ); +int msn_soap_ab_contact_del( struct im_connection *ic, bee_user_t *bu );  #endif /* __SOAP_H__ */ diff --git a/protocols/msn/tables.c b/protocols/msn/tables.c index fd7eca41..191abe43 100644 --- a/protocols/msn/tables.c +++ b/protocols/msn/tables.c @@ -82,6 +82,8 @@ const struct msn_status_code msn_status_code_list[] =  	{ 229, "Group name too long",                                   0 },  	{ 230, "Cannot remove that group",                              0 },  	{ 231, "Invalid group",                                         0 }, +	{ 240, "ADL/RML command with corrupted payload",                STATUS_FATAL }, +	{ 241, "ADL/RML command with invalid modification",             STATUS_FATAL },  	{ 280, "Switchboard failed",                                    STATUS_SB_FATAL },  	{ 281, "Transfer to switchboard failed",                        0 }, | 
