diff options
| -rw-r--r-- | irc.c | 1 | ||||
| -rw-r--r-- | irc.h | 1 | ||||
| -rw-r--r-- | irc_im.c | 8 | ||||
| -rw-r--r-- | irc_user.c | 92 | 
4 files changed, 59 insertions, 43 deletions
| @@ -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" ); @@ -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 ); @@ -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..." );  		}  	} @@ -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 )  { | 
