aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-06-11 13:34:39 +0200
committerWilmer van der Gaast <wilmer@gaast.net>2010-06-11 13:34:39 +0200
commit70ac4771ebf3358d7bec9bd6fe37cde4c23223bc (patch)
tree579cce153611c9dca6c132a4b56ac3293753d700
parent52663546cc019ebdf4a7d56f1425408e20e1d4cb (diff)
Create new MSN groups when necessary.
-rw-r--r--protocols/msn/msn.c17
-rw-r--r--protocols/msn/msn.h8
-rw-r--r--protocols/msn/msn_util.c46
-rw-r--r--protocols/msn/ns.c44
4 files changed, 104 insertions, 11 deletions
diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c
index a5807318..8b4f1a81 100644
--- a/protocols/msn/msn.c
+++ b/protocols/msn/msn.c
@@ -103,6 +103,15 @@ static void msn_logout( struct im_connection *ic )
g_free( md->grouplist[--md->groupcount] );
g_free( md->grouplist );
+ while( md->grpq )
+ {
+ struct msn_groupadd *ga = md->grpq->data;
+ g_free( ga->group );
+ g_free( ga->who );
+ g_free( ga );
+ md->grpq = g_slist_remove( md->grpq, ga );
+ }
+
g_free( md );
}
@@ -121,6 +130,14 @@ static int msn_buddy_msg( struct im_connection *ic, char *who, char *message, in
{
struct msn_switchboard *sb;
+#ifdef DEBUG
+ if( strcmp( who, "raw" ) == 0 )
+ {
+ msn_write( ic, message, strlen( message ) );
+ msn_write( ic, "\r\n", 2 );
+ }
+ else
+#endif
if( ( sb = msn_sb_by_handle( ic, who ) ) )
{
return( msn_sb_sendmessage( sb, message ) );
diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h
index e4abcb60..59036e37 100644
--- a/protocols/msn/msn.h
+++ b/protocols/msn/msn.h
@@ -69,7 +69,7 @@ struct msn_data
int trId;
- GSList *msgq;
+ GSList *msgq, *grpq;
GSList *switchboards;
int sb_failures;
time_t first_sb_failure;
@@ -120,6 +120,12 @@ struct msn_message
char *text;
};
+struct msn_groupadd
+{
+ char *who;
+ char *group;
+};
+
struct msn_handler_data
{
int fd;
diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c
index f9c10e72..24f7e10e 100644
--- a/protocols/msn/msn_util.c
+++ b/protocols/msn/msn_util.c
@@ -55,8 +55,6 @@ int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *
struct msn_data *md = ic->proto_data;
char buf[1024], *realname, groupid[8];
- realname = msn_http_encode( realname_ );
-
*groupid = '\0';
if( group )
{
@@ -67,19 +65,47 @@ int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *
g_snprintf( groupid, sizeof( groupid ), " %d", i );
break;
}
- }
-
- g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s%s\r\n", ++md->trId, list, who, realname, groupid );
- if( msn_write( ic, buf, strlen( buf ) ) )
- {
- g_free( realname );
- return( 1 );
+ if( *groupid == '\0' )
+ {
+ /* Have to create this group, it doesn't exist yet. */
+ struct msn_groupadd *ga;
+ GSList *l;
+
+ for( l = md->grpq; l; l = l->next )
+ {
+ ga = l->data;
+ if( g_strcasecmp( ga->group, group ) == 0 )
+ break;
+ }
+
+ ga = g_new0( struct msn_groupadd, 1 );
+ ga->who = g_strdup( who );
+ ga->group = g_strdup( group );
+ md->grpq = g_slist_prepend( md->grpq, ga );
+
+ if( l == NULL )
+ {
+ char *groupname = msn_http_encode( group );
+ 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
+ {
+ /* This can happen if the user's doing lots of adds to a
+ new group at once; we're still waiting for the server
+ to confirm group creation. */
+ return 1;
+ }
+ }
}
+ realname = msn_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( 0 );
+ return msn_write( ic, buf, strlen( buf ) );
}
int msn_buddy_list_remove( struct im_connection *ic, char *list, char *who )
diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c
index 8afcbe23..0be9e727 100644
--- a/protocols/msn/ns.c
+++ b/protocols/msn/ns.c
@@ -611,6 +611,50 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts )
return( 0 );
}
}
+ else if( strcmp( cmd[0], "ADG" ) == 0 )
+ {
+ char *group = g_strdup( cmd[3] );
+ int groupnum, i;
+ GSList *l, *next;
+
+ http_decode( group );
+ if( sscanf( cmd[4], "%d", &groupnum ) == 1 )
+ {
+ if( groupnum >= md->groupcount )
+ {
+ md->grouplist = g_renew( char *, md->grouplist, groupnum + 1 );
+ for( i = md->groupcount; i <= groupnum; i ++ )
+ md->grouplist[i] = NULL;
+ md->groupcount = groupnum + 1;
+ }
+ g_free( md->grouplist[groupnum] );
+ md->grouplist[groupnum] = group;
+ }
+ else
+ {
+ /* Shouldn't happen, but if it does, give up on the group. */
+ g_free( group );
+ imcb_error( ic, "Syntax error" );
+ imc_logout( ic, TRUE );
+ return 0;
+ }
+
+ for( l = md->grpq; l; l = next )
+ {
+ struct msn_groupadd *ga = l->data;
+ next = l->next;
+ if( g_strcasecmp( ga->group, group ) == 0 )
+ {
+ if( !msn_buddy_list_add( ic, "FL", ga->who, ga->who, group ) )
+ return 0;
+
+ g_free( ga->group );
+ g_free( ga->who );
+ g_free( ga );
+ md->grpq = g_slist_remove( md->grpq, ga );
+ }
+ }
+ }
else if( isdigit( cmd[0][0] ) )
{
int num = atoi( cmd[0] );