aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/msn/ns.c
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-08-15 14:02:52 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-08-15 14:02:52 +0100
commit5a7af1ba940521a65b3611e5f96ffa9306497e45 (patch)
treec78f43bd64968a4e6753aaa1f8eca2aecce9c12c /protocols/msn/ns.c
parentff27648aee17e649cdd1e47f503271e4fccbff43 (diff)
The ADL command doesn't support >150 contacts. Split it up.
Diffstat (limited to 'protocols/msn/ns.c')
-rw-r--r--protocols/msn/ns.c88
1 files changed, 60 insertions, 28 deletions
diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c
index 5bf07c3e..a599b0ba 100644
--- a/protocols/msn/ns.c
+++ b/protocols/msn/ns.c
@@ -34,6 +34,7 @@ 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 void msn_ns_send_adl_start( struct im_connection *ic );
static void msn_ns_send_adl( struct im_connection *ic );
gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
@@ -256,30 +257,32 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts )
}
else if( strcmp( cmd[0], "BLP" ) == 0 )
{
- msn_ns_send_adl( ic );
+ msn_ns_send_adl_start( ic );
}
else if( strcmp( cmd[0], "ADL" ) == 0 )
{
if( num_parts >= 3 && strcmp( cmd[2], "OK" ) == 0 )
{
- char buf[1024];
- char *fn_raw;
- char *fn;
+ msn_ns_send_adl( ic );
- if( ic->flags & OPT_LOGGED_IN )
- return 1;
-
- if( ( fn_raw = set_getstr( &ic->acc->set, "display_name" ) ) == NULL )
- fn_raw = ic->acc->user;
- fn = g_malloc( strlen( fn_raw ) * 3 + 1 );
- strcpy( fn, fn_raw );
- http_encode( fn );
-
- g_snprintf( buf, sizeof( buf ), "PRP %d MFN %s\r\n",
- ++md->trId, fn );
- g_free( fn );
-
- msn_write( ic, buf, strlen( buf ) );
+ if( md->adl_todo < 0 && !( ic->flags & OPT_LOGGED_IN ) )
+ {
+ char buf[1024];
+ char *fn_raw;
+ char *fn;
+
+ if( ( fn_raw = set_getstr( &ic->acc->set, "display_name" ) ) == NULL )
+ fn_raw = ic->acc->user;
+ fn = g_malloc( strlen( fn_raw ) * 3 + 1 );
+ strcpy( fn, fn_raw );
+ http_encode( fn );
+
+ g_snprintf( buf, sizeof( buf ), "PRP %d MFN %s\r\n",
+ ++md->trId, fn );
+ g_free( fn );
+
+ msn_write( ic, buf, strlen( buf ) );
+ }
}
else if( num_parts >= 3 )
{
@@ -732,11 +735,12 @@ static gboolean msn_ns_send_adl_1( gpointer key, gpointer value, gpointer data )
struct xt_node *adl = data, *d, *c;
struct bee_user *bu = value;
struct msn_buddy_data *bd = bu->data;
+ struct msn_data *md = bu->ic->proto_data;
char handle[strlen(bu->handle)];
char *domain;
char l[4];
- if( ( bd->flags & 7 ) == 0 )
+ if( ( bd->flags & 7 ) == 0 || ( bd->flags & MSN_BUDDY_ADL_SYNCED ) )
return FALSE;
strcpy( handle, bu->handle );
@@ -760,24 +764,27 @@ static gboolean msn_ns_send_adl_1( gpointer key, gpointer value, gpointer data )
xt_add_attr( c, "t", "1" ); /* 1 means normal, 4 means mobile? */
xt_insert_child( d, c );
- return FALSE;
+ /* Do this in batches of 100. */
+ bd->flags |= MSN_BUDDY_ADL_SYNCED;
+ return (--md->adl_todo % 140) == 0;
}
static void msn_ns_send_adl( struct im_connection *ic )
{
struct xt_node *adl;
- struct msn_data *md;
+ struct msn_data *md = ic->proto_data;
char *adls, buf[64];
- /* Dead connection? */
- if( g_slist_find( msn_connections, ic ) == NULL )
- return;
-
- md = ic->proto_data;
-
adl = xt_new_node( "ml", NULL, NULL );
xt_add_attr( adl, "l", "1" );
g_tree_foreach( md->domaintree, msn_ns_send_adl_1, adl );
+ if( adl->children == NULL )
+ {
+ /* This tells the caller that we're done now. */
+ md->adl_todo = -1;
+ xt_free_node( adl );
+ return;
+ }
adls = xt_to_string( adl );
g_snprintf( buf, sizeof( buf ), "ADL %d %zd\r\n", ++md->trId, strlen( adls ) );
@@ -785,5 +792,30 @@ static void msn_ns_send_adl( struct im_connection *ic )
msn_write( ic, adls, strlen( adls ) );
g_free( adls );
- xt_free_node( adl );
+}
+
+static void msn_ns_send_adl_start( struct im_connection *ic )
+{
+ struct msn_data *md;
+ GSList *l;
+
+ /* Dead connection? */
+ if( g_slist_find( msn_connections, ic ) == NULL )
+ return;
+
+ md = ic->proto_data;
+ md->adl_todo = 0;
+ for( l = ic->bee->users; l; l = l->next )
+ {
+ bee_user_t *bu = l->data;
+ struct msn_buddy_data *bd = bu->data;
+
+ if( bu->ic != ic || ( bd->flags & 7 ) == 0 )
+ continue;
+
+ bd->flags &= ~MSN_BUDDY_ADL_SYNCED;
+ md->adl_todo++;
+ }
+
+ msn_ns_send_adl( ic );
}