aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitlbee.c3
-rw-r--r--doc/user-guide/commands.xml14
-rw-r--r--irc_commands.c11
-rw-r--r--irc_im.c27
-rw-r--r--irc_user.c4
-rw-r--r--protocols/bee.h1
-rw-r--r--protocols/bee_user.c1
-rw-r--r--protocols/nogaim.c3
-rw-r--r--root_commands.c4
9 files changed, 59 insertions, 9 deletions
diff --git a/bitlbee.c b/bitlbee.c
index 78f4b4e5..5ced6469 100644
--- a/bitlbee.c
+++ b/bitlbee.c
@@ -371,7 +371,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 @@
</description>
</bitlbee-setting>
+ <bitlbee-setting name="translate_to_nicks" type="boolean" scope="channel">
+ <default>true</default>
+
+ <description>
+ <para>
+ 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.
+ </para>
+
+ <para>
+ 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.
+ </para>
+ </description>
+ </bitlbee-setting>
+
<bitlbee-setting name="type" type="string" scope="channel">
<default>control</default>
<possible-values>control, chat</possible-values>
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_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/irc_user.c b/irc_user.c
index 70f324c7..8db1de28 100644
--- a/irc_user.c
+++ b/irc_user.c
@@ -120,11 +120,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/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 );
}
diff --git a/root_commands.c b/root_commands.c
index daaebb95..cf448e8d 100644
--- a/root_commands.c
+++ b/root_commands.c
@@ -679,7 +679,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] );
@@ -695,7 +695,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] );
}