aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--irc.c1
-rw-r--r--irc.h1
-rw-r--r--irc_im.c8
-rw-r--r--irc_user.c92
4 files changed, 59 insertions, 43 deletions
diff --git a/irc.c b/irc.c
index fb720088..650917fe 100644
--- a/irc.c
+++ b/irc.c
@@ -107,6 +107,7 @@ irc_t *irc_new( int fd )
s = set_add( &b->set, "display_timestamps", "true", set_eval_bool, irc );
s = set_add( &b->set, "handle_unknown", "add_channel", NULL, irc );
s = set_add( &b->set, "lcnicks", "true", set_eval_bool, irc );
+ s = set_add( &b->set, "offline_user_quits", "true", set_eval_bool, irc );
s = set_add( &b->set, "ops", "both", set_eval_irc_channel_ops, irc );
s = set_add( &b->set, "paste_buffer", "false", set_eval_bool, irc );
s->old_key = g_strdup( "buddy_sendbuffer" );
diff --git a/irc.h b/irc.h
index 4663c5b9..96b05d44 100644
--- a/irc.h
+++ b/irc.h
@@ -272,6 +272,7 @@ 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 );
gint irc_user_cmp( gconstpointer a_, gconstpointer b_ );
const char *irc_user_get_away( irc_user_t *iu );
+void irc_user_quit( irc_user_t *iu, const char *msg );
/* irc_util.c */
char *set_eval_timezone( struct set *set, char *value );
diff --git a/irc_im.c b/irc_im.c
index dcba6f8f..caf0e38e 100644
--- a/irc_im.c
+++ b/irc_im.c
@@ -107,6 +107,14 @@ static gboolean bee_irc_user_status( bee_t *bee, bee_user_t *bu, bee_user_t *old
if( g_hash_table_lookup( irc->watches, iu->key ) )
irc_send_num( irc, 601, "%s %s %s %d :%s", iu->nick, iu->user,
iu->host, (int) time( NULL ), "logged offline" );
+
+ /* Send a QUIT since those will also show up in any
+ query windows the user may have, plus it's only
+ one QUIT instead of possibly many (in case of
+ multiple control chans). If there's a channel that
+ shows offline people, a JOIN will follow. */
+ if( set_getbool( &bee->set, "offline_user_quits" ) )
+ irc_user_quit( iu, "Leaving..." );
}
}
diff --git a/irc_user.c b/irc_user.c
index 98145ae1..fa509a45 100644
--- a/irc_user.c
+++ b/irc_user.c
@@ -51,56 +51,47 @@ irc_user_t *irc_user_new( irc_t *irc, const char *nick )
int irc_user_free( irc_t *irc, irc_user_t *iu )
{
- GSList *l;
- gboolean send_quit = FALSE;
+ static struct im_connection *last_ic;
+ static char *msg;
if( !iu )
return 0;
- irc->users = g_slist_remove( irc->users, iu );
- g_hash_table_remove( irc->nick_user_hash, iu->key );
-
- for( l = irc->channels; l; l = l->next )
- send_quit |= irc_channel_del_user( (irc_channel_t*) l->data, iu, TRUE, NULL );
-
- if( send_quit )
+ if( iu->bu &&
+ ( iu->bu->ic->flags & OPT_LOGGING_OUT ) &&
+ iu->bu->ic != last_ic )
{
- static struct im_connection *last_ic;
- static char *msg;
+ char host_prefix[] = "bitlbee.";
+ char *s;
- if( iu->bu &&
- ( iu->bu->ic->flags & OPT_LOGGING_OUT ) &&
- iu->bu->ic != last_ic )
- {
- char host_prefix[] = "bitlbee.";
- char *s;
-
- /* Irssi recognises netsplits by quitmsgs with two
- hostnames, where a hostname is a "word" with one
- of more dots. Mangle no-dot hostnames a bit. */
- if( strchr( irc->root->host, '.' ) )
- *host_prefix = '\0';
-
- last_ic = iu->bu->ic;
- g_free( msg );
- if( !set_getbool( &irc->b->set, "simulate_netsplit" ) )
- msg = g_strdup( "Account off-line" );
- else if( ( s = strchr( iu->bu->ic->acc->user, '@' ) ) )
- msg = g_strdup_printf( "%s%s %s", host_prefix,
- irc->root->host, s + 1 );
- else
- msg = g_strdup_printf( "%s%s %s.%s",
- host_prefix, irc->root->host,
- iu->bu->ic->acc->prpl->name, irc->root->host );
- }
- else if( !iu->bu || !( iu->bu->ic->flags & OPT_LOGGING_OUT ) )
- {
- g_free( msg );
- msg = g_strdup( "Removed" );
- last_ic = NULL;
- }
- irc_send_quit( iu, msg );
+ /* Irssi recognises netsplits by quitmsgs with two
+ hostnames, where a hostname is a "word" with one
+ of more dots. Mangle no-dot hostnames a bit. */
+ if( strchr( irc->root->host, '.' ) )
+ *host_prefix = '\0';
+
+ last_ic = iu->bu->ic;
+ g_free( msg );
+ if( !set_getbool( &irc->b->set, "simulate_netsplit" ) )
+ msg = g_strdup( "Account off-line" );
+ else if( ( s = strchr( iu->bu->ic->acc->user, '@' ) ) )
+ msg = g_strdup_printf( "%s%s %s", host_prefix,
+ irc->root->host, s + 1 );
+ else
+ msg = g_strdup_printf( "%s%s %s.%s",
+ host_prefix, irc->root->host,
+ iu->bu->ic->acc->prpl->name, irc->root->host );
+ }
+ else if( !iu->bu || !( iu->bu->ic->flags & OPT_LOGGING_OUT ) )
+ {
+ g_free( msg );
+ msg = g_strdup( "Removed" );
+ last_ic = NULL;
}
+ irc_user_quit( iu, msg );
+
+ irc->users = g_slist_remove( irc->users, iu );
+ g_hash_table_remove( irc->nick_user_hash, iu->key );
g_free( iu->nick );
if( iu->nick != iu->user ) g_free( iu->user );
@@ -204,6 +195,21 @@ const char *irc_user_get_away( irc_user_t *iu )
return NULL;
}
+void irc_user_quit( irc_user_t *iu, const char *msg )
+{
+ GSList *l;
+ gboolean send_quit = FALSE;
+
+ if( !iu )
+ return;
+
+ for( l = iu->irc->channels; l; l = l->next )
+ send_quit |= irc_channel_del_user( (irc_channel_t*) l->data, iu, TRUE, NULL );
+
+ if( send_quit )
+ irc_send_quit( iu, msg );
+}
+
/* User-type dependent functions, for root/NickServ: */
static gboolean root_privmsg( irc_user_t *iu, const char *msg )
{