From 69b896b5967e5d13b1c60c68cb3bc7d4a0d5cd06 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 5 Jul 2010 13:01:28 +0100 Subject: When addressing people in a chatroom, try to translate the nickname to the original unstripped version (without ugly underscores, also). --- bitlbee.c | 3 ++- doc/user-guide/commands.xml | 14 ++++++++++++++ irc_im.c | 27 ++++++++++++++++++++++++++- protocols/bee.h | 1 + protocols/bee_user.c | 1 + protocols/nogaim.c | 3 +++ 6 files changed, 47 insertions(+), 2 deletions(-) diff --git a/bitlbee.c b/bitlbee.c index d0d95e67..5e93f733 100644 --- a/bitlbee.c +++ b/bitlbee.c @@ -369,7 +369,8 @@ gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond ) { /* Try to save data for all active connections (if desired). */ while( irc_connection_list != NULL ) - irc_free( irc_connection_list->data ); + irc_abort( irc_connection_list->data, FALSE, + "BitlBee server shutting down" ); /* We'll only reach this point when not running in inetd mode: */ b_main_quit(); diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml index 889b6165..4154fb27 100644 --- a/doc/user-guide/commands.xml +++ b/doc/user-guide/commands.xml @@ -1092,6 +1092,20 @@ + + true + + + + IRC's nickname namespace is quite limited compared to most IM protocols. Not any non-ASCII characters are allowed, in fact nicknames have to be mostly alpha-numeric. Also, BitlBee has to add underscores sometimes to avoid nickname collisions. + + + + While normally the BitlBee user is the only one seeing these names, they may be exposed to other chatroom participants for example when addressing someone in the channel (with or without tab completion). By default BitlBee will translate these stripped nicknames back to the original nick. If you don't want this, disable this setting. + + + + control control, chat diff --git a/irc_im.c b/irc_im.c index c900e7ff..d7906cd5 100644 --- a/irc_im.c +++ b/irc_im.c @@ -602,10 +602,31 @@ static gboolean bee_irc_channel_chat_privmsg_cb( gpointer data, gint fd, b_input static gboolean bee_irc_channel_chat_privmsg( irc_channel_t *ic, const char *msg ) { struct groupchat *c = ic->data; + char *trans = NULL, *s; if( c == NULL ) return FALSE; - else if( set_getbool( &ic->irc->b->set, "paste_buffer" ) ) + + if( set_getbool( &ic->set, "translate_to_nicks" ) ) + { + char nick[MAX_NICK_LENGTH+1]; + irc_user_t *iu; + + strncpy( nick, msg, MAX_NICK_LENGTH ); + nick[MAX_NICK_LENGTH] = '\0'; + if( ( s = strchr( nick, ':' ) ) || ( s = strchr( nick, ',' ) ) ) + { + *s = '\0'; + if( ( iu = irc_user_by_name( ic->irc, nick ) ) && + iu->bu->nick && irc_channel_has_user( ic, iu ) ) + { + trans = g_strconcat( iu->bu->nick, msg + ( s - nick ), NULL ); + msg = trans; + } + } + } + + if( set_getbool( &ic->irc->b->set, "paste_buffer" ) ) { int delay; @@ -622,11 +643,13 @@ static gboolean bee_irc_channel_chat_privmsg( irc_channel_t *ic, const char *msg ic->pastebuf_timer = b_timeout_add( delay, bee_irc_channel_chat_privmsg_cb, ic ); + g_free( trans ); return TRUE; } else bee_chat_msg( ic->irc->b, c, msg, 0 ); + g_free( trans ); return TRUE; } @@ -746,6 +769,7 @@ static gboolean bee_irc_channel_init( irc_channel_t *ic ) set_add( &ic->set, "chat_type", "groupchat", set_eval_chat_type, ic ); set_add( &ic->set, "nick", NULL, NULL, ic ); set_add( &ic->set, "room", NULL, NULL, ic ); + set_add( &ic->set, "translate_to_nicks", "true", set_eval_bool, ic ); /* chat_type == groupchat */ ic->flags |= IRC_CHANNEL_TEMP; @@ -789,6 +813,7 @@ static gboolean bee_irc_channel_free( irc_channel_t *ic ) set_del( &ic->set, "chat_type" ); set_del( &ic->set, "nick" ); set_del( &ic->set, "room" ); + set_del( &ic->set, "translate_to_nicks" ); ic->flags &= ~IRC_CHANNEL_TEMP; diff --git a/protocols/bee.h b/protocols/bee.h index e82913d6..4b6a1f4a 100644 --- a/protocols/bee.h +++ b/protocols/bee.h @@ -61,6 +61,7 @@ typedef struct bee_user struct im_connection *ic; char *handle; char *fullname; + char *nick; struct bee_group *group; bee_user_flags_t flags; diff --git a/protocols/bee_user.c b/protocols/bee_user.c index faa2acb7..4399a566 100644 --- a/protocols/bee_user.c +++ b/protocols/bee_user.c @@ -59,6 +59,7 @@ int bee_user_free( bee_t *bee, bee_user_t *bu ) g_free( bu->handle ); g_free( bu->fullname ); + g_free( bu->nick ); g_free( bu->status ); g_free( bu->status_msg ); g_free( bu ); diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 0998291b..c23b0a3a 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -427,6 +427,9 @@ void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const c if( !bu || !nick ) return; + g_free( bu->nick ); + bu->nick = g_strdup( nick ); + if( bee->ui->user_nick_hint ) bee->ui->user_nick_hint( bee, bu, nick ); } -- cgit v1.2.3 From 9a9b520df6044cfc034f9736fb97660a46e879b9 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 8 Jul 2010 23:31:01 +0100 Subject: Allow nick changes if they're only different in capitalisation, fixed faulty responses in the NICK command, and fixing crash bug in nick changes before finishing login. --- irc_commands.c | 11 +++++++---- irc_user.c | 4 +++- root_commands.c | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/irc_commands.c b/irc_commands.c index 197a7e6e..0573601d 100644 --- a/irc_commands.c +++ b/irc_commands.c @@ -71,16 +71,18 @@ static void irc_cmd_user( irc_t *irc, char **cmd ) static void irc_cmd_nick( irc_t *irc, char **cmd ) { - if( irc_user_by_name( irc, cmd[1] ) ) + irc_user_t *iu; + + if( ( iu = irc_user_by_name( irc, cmd[1] ) ) && iu != irc->user ) { - irc_send_num( irc, 433, ":This nick is already in use" ); + irc_send_num( irc, 433, "%s :This nick is already in use", cmd[1] ); } else if( !nick_ok( cmd[1] ) ) { /* [SH] Invalid characters. */ - irc_send_num( irc, 432, ":This nick contains invalid characters" ); + irc_send_num( irc, 432, "%s :This nick contains invalid characters", cmd[1] ); } - else if( irc->user->nick ) + else if( irc->status & USTATUS_LOGGED_IN ) { if( irc->status & USTATUS_IDENTIFIED ) { @@ -97,6 +99,7 @@ static void irc_cmd_nick( irc_t *irc, char **cmd ) } else { + g_free( irc->user->nick ); irc->user->nick = g_strdup( cmd[1] ); irc_check_login( irc ); diff --git a/irc_user.c b/irc_user.c index cb7ea1e7..7d29cae0 100644 --- a/irc_user.c +++ b/irc_user.c @@ -119,11 +119,13 @@ irc_user_t *irc_user_by_name( irc_t *irc, const char *nick ) int irc_user_set_nick( irc_user_t *iu, const char *new ) { irc_t *irc = iu->irc; + irc_user_t *new_iu; char key[strlen(new)+1]; GSList *cl; strcpy( key, new ); - if( iu == NULL || !nick_lc( key ) || irc_user_by_name( irc, new ) ) + if( iu == NULL || !nick_lc( key ) || + ( ( new_iu = irc_user_by_name( irc, new ) ) && new_iu != iu ) ) return 0; for( cl = irc->channels; cl; cl = cl->next ) diff --git a/root_commands.c b/root_commands.c index 62fe1e79..5c5ead7b 100644 --- a/root_commands.c +++ b/root_commands.c @@ -661,7 +661,7 @@ static void cmd_info( irc_t *irc, char **cmd ) static void cmd_rename( irc_t *irc, char **cmd ) { - irc_user_t *iu; + irc_user_t *iu, *old; iu = irc_user_by_name( irc, cmd[1] ); @@ -677,7 +677,7 @@ static void cmd_rename( irc_t *irc, char **cmd ) { irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] ); } - else if( irc_user_by_name( irc, cmd[2] ) ) + else if( ( old = irc_user_by_name( irc, cmd[2] ) ) && old != iu ) { irc_usermsg( irc, "Nick `%s' already exists", cmd[2] ); } -- cgit v1.2.3