diff options
-rw-r--r-- | doc/user-guide/commands.xml | 11 | ||||
-rw-r--r-- | protocols/msn/msn.c | 31 | ||||
-rw-r--r-- | protocols/msn/msn.h | 1 | ||||
-rw-r--r-- | protocols/msn/msn_util.c | 16 | ||||
-rw-r--r-- | protocols/msn/ns.c | 59 |
5 files changed, 78 insertions, 40 deletions
diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml index df99c1fc..833ea00f 100644 --- a/doc/user-guide/commands.xml +++ b/doc/user-guide/commands.xml @@ -608,6 +608,17 @@ </bitlbee-setting> + <bitlbee-setting name="local_display_name" type="boolean" scope="account"> + <default>false</default> + + <description> + <para> + Mostly meant to work around a bug in MSN servers (forgetting the display name set by the user), this setting tells BitlBee to store your display name locally and set this name on the MSN servers when connecting. + </para> + </description> + + </bitlbee-setting> + <bitlbee-setting name="mail_notifications" type="boolean" scope="account"> <default>false</default> diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index 8930847d..37f6e1be 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -30,16 +30,13 @@ int msn_chat_id; GSList *msn_connections; GSList *msn_switchboards; -static char *msn_set_display_name( set_t *set, char *value ); +static char *set_eval_display_name( set_t *set, char *value ); static void msn_init( account_t *acc ) { - set_t *s; - - s = set_add( &acc->set, "display_name", NULL, msn_set_display_name, acc ); - s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY; - - s = set_add( &acc->set, "mail_notifications", "false", set_eval_bool, 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_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc ); } static void msn_login( account_t *acc ) @@ -166,7 +163,7 @@ static void msn_set_away( struct im_connection *ic, char *state, char *message ) static void msn_set_my_name( struct im_connection *ic, char *info ) { - msn_set_display_name( set_find( &ic->acc->set, "display_name" ), info ); + msn_set_display_name( ic, info ); } static void msn_get_info(struct im_connection *ic, char *who) @@ -282,18 +279,14 @@ static int msn_send_typing( struct im_connection *ic, char *who, int typing ) return( 1 ); } -static char *msn_set_display_name( set_t *set, char *value ) +static char *set_eval_display_name( set_t *set, char *value ) { account_t *acc = set->data; struct im_connection *ic = acc->ic; - struct msn_data *md; - char buf[1024], *fn; - /* Double-check. */ + /* Allow any name if we're offline. */ if( ic == NULL ) - return NULL; - - md = ic->proto_data; + return value; if( strlen( value ) > 129 ) { @@ -301,16 +294,10 @@ static char *msn_set_display_name( set_t *set, char *value ) return NULL; } - fn = msn_http_encode( value ); - - g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn ); - msn_write( ic, 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; + return msn_set_display_name( ic, value ) ? value : NULL; } void msn_initmodule() diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 84914bc3..02d180b6 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -160,6 +160,7 @@ 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 ); /* 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 668a8b8a..9c9d2720 100644 --- a/protocols/msn/msn_util.c +++ b/protocols/msn/msn_util.c @@ -37,10 +37,10 @@ int msn_write( struct im_connection *ic, char *s, int len ) { imcb_error( ic, "Short write() to main server" ); imc_logout( ic, TRUE ); - return( 0 ); + return 0; } - return( 1 ); + return 1; } int msn_logged_in( struct im_connection *ic ) @@ -376,3 +376,15 @@ void msn_msgq_purge( struct im_connection *ic, GSList **list ) imcb_log( ic, "%s", ret->str ); 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; +} diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index d78d753a..cb10df30 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -34,6 +34,7 @@ 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_auth_got_passport_token( struct msn_auth_data *mad ); +static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name ); gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ) { @@ -230,25 +231,10 @@ 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; - if( num_parts == 7 ) - { - 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] ); - } - } + msn_ns_got_display_name( ic, cmd[4] ); else - { imcb_log( ic, "Warning: Friendly name in server response was corrupted" ); - } imcb_log( ic, "Authenticated, getting buddy list" ); @@ -566,6 +552,9 @@ 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 ) @@ -596,6 +585,7 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) 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." ); @@ -745,3 +735,40 @@ static void msn_auth_got_passport_token( struct msn_auth_data *mad ) imc_logout( ic, TRUE ); } } + +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 ); + + g_free( s->value ); + s->value = g_strdup( name ); + return TRUE; + } +} |