aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/msn
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/msn')
-rw-r--r--protocols/msn/msn.c99
-rw-r--r--protocols/msn/msn.h1
-rw-r--r--protocols/msn/msn_util.c65
-rw-r--r--protocols/msn/ns.c16
-rw-r--r--protocols/msn/passport.c23
5 files changed, 112 insertions, 92 deletions
diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c
index a8d85a66..f8686835 100644
--- a/protocols/msn/msn.c
+++ b/protocols/msn/msn.c
@@ -26,36 +26,45 @@
#include "nogaim.h"
#include "msn.h"
-static void msn_login( struct aim_user *acct )
+static char *msn_set_display_name( set_t *set, char *value );
+
+static void msn_acc_init( account_t *acc )
{
- struct gaim_connection *gc = new_gaim_conn( acct );
- struct msn_data *md = g_new0( struct msn_data, 1 );
+ set_t *s;
- set_login_progress( gc, 1, "Connecting" );
+ s = set_add( &acc->set, "display_name", NULL, msn_set_display_name, acc );
+ s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY;
+}
+
+static void msn_login( account_t *acc )
+{
+ struct gaim_connection *gc = new_gaim_conn( acc );
+ struct msn_data *md = g_new0( struct msn_data, 1 );
gc->proto_data = md;
md->fd = -1;
- if( strchr( acct->username, '@' ) == NULL )
+ if( strchr( acc->user, '@' ) == NULL )
{
hide_login_progress( gc, "Invalid account name" );
signoff( gc );
return;
}
+ set_login_progress( gc, 1, "Connecting" );
+
md->fd = proxy_connect( "messenger.hotmail.com", 1863, msn_ns_connected, gc );
if( md->fd < 0 )
{
hide_login_progress( gc, "Could not connect to server" );
signoff( gc );
+ return;
}
- else
- {
- md->gc = gc;
- md->away_state = msn_away_state_list;
-
- msn_connections = g_slist_append( msn_connections, gc );
- }
+
+ md->gc = gc;
+ md->away_state = msn_away_state_list;
+
+ msn_connections = g_slist_append( msn_connections, gc );
}
static void msn_close( struct gaim_connection *gc )
@@ -211,36 +220,7 @@ static void msn_set_away( struct gaim_connection *gc, char *state, char *message
static void msn_set_info( struct gaim_connection *gc, char *info )
{
- int i;
- char buf[1024], *fn, *s;
- struct msn_data *md = gc->proto_data;
-
- if( strlen( info ) > 129 )
- {
- do_error_dialog( gc, "Maximum name length exceeded", "MSN" );
- return;
- }
-
- /* Of course we could use http_encode() here, but when we encode
- every character, the server is less likely to complain about the
- chosen name. However, the MSN server doesn't seem to like escaped
- non-ASCII chars, so we keep those unescaped. */
- s = fn = g_new0( char, strlen( info ) * 3 + 1 );
- for( i = 0; info[i]; i ++ )
- if( info[i] & 128 )
- {
- *s = info[i];
- s ++;
- }
- else
- {
- g_snprintf( s, 4, "%%%02X", info[i] );
- s += 3;
- }
-
- g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn );
- msn_write( gc, buf, strlen( buf ) );
- g_free( fn );
+ msn_set_display_name( set_find( &gc->acc->set, "display_name" ), info );
}
static void msn_get_info(struct gaim_connection *gc, char *who)
@@ -379,11 +359,44 @@ static int msn_send_typing( struct gaim_connection *gc, char *who, int typing )
return( 1 );
}
+static char *msn_set_display_name( set_t *set, char *value )
+{
+ account_t *acc = set->data;
+ struct gaim_connection *gc = acc->gc;
+ struct msn_data *md;
+ char buf[1024], *fn;
+
+ /* Double-check. */
+ if( gc == NULL )
+ return NULL;
+
+ md = gc->proto_data;
+
+ if( strlen( value ) > 129 )
+ {
+ serv_got_crap( gc, "Maximum name length exceeded" );
+ return NULL;
+ }
+
+ fn = msn_http_encode( value );
+
+ g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn );
+ msn_write( gc, buf, strlen( buf ) );
+ g_free( fn );
+
+ /* 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 value;
+}
+
void msn_init()
{
struct prpl *ret = g_new0(struct prpl, 1);
+
ret->name = "msn";
ret->login = msn_login;
+ ret->acc_init = msn_acc_init;
ret->close = msn_close;
ret->send_im = msn_send_im;
ret->away_states = msn_away_states;
@@ -403,7 +416,7 @@ void msn_init()
ret->add_deny = msn_add_deny;
ret->rem_deny = msn_rem_deny;
ret->send_typing = msn_send_typing;
- ret->cmp_buddynames = g_strcasecmp;
+ ret->handle_cmp = g_strcasecmp;
register_protocol(ret);
}
diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h
index dbbb6aa0..b4777d41 100644
--- a/protocols/msn/msn.h
+++ b/protocols/msn/msn.h
@@ -156,6 +156,7 @@ void msn_buddy_ask( struct gaim_connection *gc, 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 );
/* tables.c */
const struct msn_away_state *msn_away_state_by_number( int number );
diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c
index c3bd73cc..ff4c148c 100644
--- a/protocols/msn/msn_util.c
+++ b/protocols/msn/msn_util.c
@@ -53,31 +53,15 @@ int msn_logged_in( struct gaim_connection *gc )
int msn_buddy_list_add( struct gaim_connection *gc, char *list, char *who, char *realname_ )
{
struct msn_data *md = gc->proto_data;
- GSList *l, **lp = NULL;
char buf[1024], *realname;
- if( strcmp( list, "AL" ) == 0 )
- lp = &gc->permit;
- else if( strcmp( list, "BL" ) == 0 )
- lp = &gc->deny;
-
- if( lp )
- for( l = *lp; l; l = l->next )
- if( g_strcasecmp( l->data, who ) == 0 )
- return( 1 );
-
- realname = g_new0( char, strlen( realname_ ) * 3 + 1 );
- strcpy( realname, realname_ );
- http_encode( realname );
+ realname = msn_http_encode( realname_ );
g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s\r\n", ++md->trId, list, who, realname );
if( msn_write( gc, buf, strlen( buf ) ) )
{
g_free( realname );
- if( lp )
- *lp = g_slist_append( *lp, g_strdup( who ) );
-
return( 1 );
}
@@ -89,32 +73,11 @@ int msn_buddy_list_add( struct gaim_connection *gc, char *list, char *who, char
int msn_buddy_list_remove( struct gaim_connection *gc, char *list, char *who )
{
struct msn_data *md = gc->proto_data;
- GSList *l = NULL, **lp = NULL;
char buf[1024];
- if( strcmp( list, "AL" ) == 0 )
- lp = &gc->permit;
- else if( strcmp( list, "BL" ) == 0 )
- lp = &gc->deny;
-
- if( lp )
- {
- for( l = *lp; l; l = l->next )
- if( g_strcasecmp( l->data, who ) == 0 )
- break;
-
- if( !l )
- return( 1 );
- }
-
g_snprintf( buf, sizeof( buf ), "REM %d %s %s\r\n", ++md->trId, list, who );
if( msn_write( gc, buf, strlen( buf ) ) )
- {
- if( lp )
- *lp = g_slist_remove( *lp, l->data );
-
return( 1 );
- }
return( 0 );
}
@@ -349,3 +312,29 @@ 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;
+}
diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c
index e4c2b68c..9774f3e2 100644
--- a/protocols/msn/ns.c
+++ b/protocols/msn/ns.c
@@ -222,11 +222,19 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts )
}
else if( num_parts == 7 && strcmp( cmd[2], "OK" ) == 0 )
{
+ set_t *s;
+
http_decode( cmd[4] );
strncpy( gc->displayname, cmd[4], sizeof( gc->displayname ) );
gc->displayname[sizeof(gc->displayname)-1] = 0;
+ if( ( s = set_find( &gc->acc->set, "display_name" ) ) )
+ {
+ g_free( s->value );
+ s->value = g_strdup( cmd[4] );
+ }
+
set_login_progress( gc, 1, "Authenticated, getting buddy list" );
g_snprintf( buf, sizeof( buf ), "SYN %d 0\r\n", ++md->trId );
@@ -516,9 +524,17 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts )
if( g_strcasecmp( cmd[3], gc->username ) == 0 )
{
+ set_t *s;
+
http_decode( cmd[4] );
strncpy( gc->displayname, cmd[4], sizeof( gc->displayname ) );
gc->displayname[sizeof(gc->displayname)-1] = 0;
+
+ if( ( s = set_find( &gc->acc->set, "display_name" ) ) )
+ {
+ g_free( s->value );
+ s->value = g_strdup( cmd[4] );
+ }
}
else
{
diff --git a/protocols/msn/passport.c b/protocols/msn/passport.c
index dd1d9b6f..9fe6a174 100644
--- a/protocols/msn/passport.c
+++ b/protocols/msn/passport.c
@@ -58,6 +58,7 @@ static int passport_get_id_real( gpointer func, gpointer data, char *header )
rep = g_new0( struct passport_reply, 1 );
rep->data = data;
rep->func = func;
+ rep->header = header;
server = g_strdup( prd_cached );
dummy = strchr( server, '/' );
@@ -124,10 +125,14 @@ static void passport_get_id_ready( struct http_request *req )
static char *passport_create_header( char *cookie, char *email, char *pwd )
{
- char *buffer = g_new0( char, 2048 );
+ char *buffer;
char *currenttoken;
char *email_enc, *pwd_enc;
+ currenttoken = strstr( cookie, "lc=" );
+ if( currenttoken == NULL )
+ return NULL;
+
email_enc = g_new0( char, strlen( email ) * 3 + 1 );
strcpy( email_enc, email );
http_encode( email_enc );
@@ -136,20 +141,15 @@ static char *passport_create_header( char *cookie, char *email, char *pwd )
strcpy( pwd_enc, pwd );
http_encode( pwd_enc );
- currenttoken = strstr( cookie, "lc=" );
- if( currenttoken == NULL )
- return( NULL );
-
- g_snprintf( buffer, 2048,
- "Authorization: Passport1.4 OrgVerb=GET,"
- "OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom,"
- "sign-in=%s,pwd=%s,%s", email_enc, pwd_enc,
- currenttoken );
+ buffer = g_strdup_printf( "Authorization: Passport1.4 OrgVerb=GET,"
+ "OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom,"
+ "sign-in=%s,pwd=%s,%s", email_enc, pwd_enc,
+ currenttoken );
g_free( email_enc );
g_free( pwd_enc );
- return( buffer );
+ return buffer;
}
static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header )
@@ -211,6 +211,7 @@ static void passport_retrieve_dalogin_ready( struct http_request *req )
if( passport_get_id_real( rep->func, rep->data, rep->header ) )
{
+ rep->header = NULL;
destroy_reply( rep );
return;
}