diff options
| -rw-r--r-- | doc/user-guide/commands.xml | 10 | ||||
| -rw-r--r-- | irc.c | 1 | ||||
| -rw-r--r-- | lib/oauth.c | 6 | ||||
| -rw-r--r-- | lib/oauth.h | 6 | ||||
| -rw-r--r-- | protocols/nogaim.c | 92 | ||||
| -rw-r--r-- | protocols/twitter/twitter.c | 4 | 
6 files changed, 94 insertions, 25 deletions
| diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml index 9fcc91da..af2c5eb2 100644 --- a/doc/user-guide/commands.xml +++ b/doc/user-guide/commands.xml @@ -860,6 +860,16 @@  		</description>  	</bitlbee-setting> +	<bitlbee-setting name="show_offline" type="boolean" scope="global"> +		<default>true</default> + +		<description> +			<para> +				If enabled causes BitlBee to also show offline users in Channel. Online-users will get op, away-users voice and offline users none of both. This option takes effect as soon as you reconnect. +			</para> +		</description> +	</bitlbee-setting> +  	<bitlbee-setting name="simulate_netsplit" type="boolean" scope="global">  		<default>true</default> @@ -200,6 +200,7 @@ irc_t *irc_new( int fd )  	s = set_add( &irc->set, "query_order", "lifo", NULL, irc );  	s = set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc );  	s = set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); +	s = set_add( &irc->set, "show_offline", "false", set_eval_bool, irc );  	s = set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc );  	s = set_add( &irc->set, "status", NULL,  set_eval_away_status, irc );  	s->flags |= SET_NULL_OK; diff --git a/lib/oauth.c b/lib/oauth.c index 8012c37a..c60a5a52 100644 --- a/lib/oauth.c +++ b/lib/oauth.c @@ -232,7 +232,7 @@ void oauth_info_free( struct oauth_info *info )  	}  } -static void oauth_add_default_params( GSList **params, struct oauth_service *sp ) +static void oauth_add_default_params( GSList **params, const struct oauth_service *sp )  {  	char *s; @@ -293,7 +293,7 @@ static void *oauth_post_request( const char *url, GSList **params_, http_input_f  static void oauth_request_token_done( struct http_request *req ); -struct oauth_info *oauth_request_token( struct oauth_service *sp, oauth_cb func, void *data ) +struct oauth_info *oauth_request_token( const struct oauth_service *sp, oauth_cb func, void *data )  {  	struct oauth_info *st = g_new0( struct oauth_info, 1 );  	GSList *params = NULL; @@ -438,7 +438,7 @@ char *oauth_to_string( struct oauth_info *oi )  	return ret;  } -struct oauth_info *oauth_from_string( char *in, struct oauth_service *sp ) +struct oauth_info *oauth_from_string( char *in, const struct oauth_service *sp )  {  	struct oauth_info *oi = g_new0( struct oauth_info, 1 );  	GSList *params = NULL; diff --git a/lib/oauth.h b/lib/oauth.h index 6b51dc2c..5dfe0ae5 100644 --- a/lib/oauth.h +++ b/lib/oauth.h @@ -39,7 +39,7 @@ typedef enum  struct oauth_info  {  	oauth_stage_t stage; -	struct oauth_service *sp; +	const struct oauth_service *sp;  	oauth_cb func;  	void *data; @@ -67,7 +67,7 @@ struct oauth_service     Request an initial anonymous token which can be used to construct an     authorization URL for the user. This is passed to the callback function     in a struct oauth_info. */ -struct oauth_info *oauth_request_token( struct oauth_service *sp, oauth_cb func, void *data ); +struct oauth_info *oauth_request_token( const struct oauth_service *sp, oauth_cb func, void *data );  /* http://oauth.net/core/1.0a/#auth_step3 (section 6.3)     The user gets a PIN or so which we now exchange for the final access @@ -87,4 +87,4 @@ void oauth_info_free( struct oauth_info *info );  /* Convert to and back from strings, for easier saving. */  char *oauth_to_string( struct oauth_info *oi ); -struct oauth_info *oauth_from_string( char *in, struct oauth_service *sp ); +struct oauth_info *oauth_from_string( char *in, const struct oauth_service *sp ); diff --git a/protocols/nogaim.c b/protocols/nogaim.c index fca8b302..2248d11e 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -656,7 +656,18 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags,  	g_free( u->status_msg );  	u->away = u->status_msg = NULL; -	if( ( flags & OPT_LOGGED_IN ) && !u->online ) +	if( set_getbool( &ic->irc->set, "show_offline" ) && !u->online ) +	{ +		/* always set users as online */ +		irc_spawn( ic->irc, u ); +		u->online = 1; +		if( !( flags & OPT_LOGGED_IN ) ) +		{ +			/* set away message if user isn't really online */ +			u->away = g_strdup( "User is offline" ); +		} +	} +	else if( ( flags & OPT_LOGGED_IN ) && !u->online )  	{  		irc_spawn( ic->irc, u );  		u->online = 1; @@ -665,14 +676,30 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags,  	{  		struct groupchat *c; -		irc_kill( ic->irc, u ); -		u->online = 0; -		 -		/* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ -		for( c = ic->groupchats; c; c = c->next ) -			remove_chat_buddy_silent( c, handle ); +		if( set_getbool( &ic->irc->set, "show_offline" ) ) +		{ +			/* keep offline users in channel and set away message to "offline" */ +			u->away = g_strdup( "User is offline" ); + +			/* Keep showing him/her in the control channel but not in groupchats. */ +			for( c = ic->groupchats; c; c = c->next ) +			{ +				if( remove_chat_buddy_silent( c, handle ) && c->joined ) +					irc_part( c->ic->irc, u, c->channel ); +			} +		} +		else +		{ +			/* kill offline users */ +			irc_kill( ic->irc, u ); +			u->online = 0; + +			/* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ +			for( c = ic->groupchats; c; c = c->next ) +				remove_chat_buddy_silent( c, handle ); +		}  	} -	 +  	if( flags & OPT_AWAY )  	{  		if( state && message ) @@ -697,11 +724,8 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags,  		u->status_msg = g_strdup( message );  	} -	/* LISPy... */ -	if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */ -	    ( u->online ) &&						/* Don't touch offline people */ -	    ( ( ( u->online != oo ) && !u->away ) ||			/* Voice joining people */ -	      ( ( u->online == oo ) && ( oa == !u->away ) ) ) )		/* (De)voice people changing state */ +	/* early if-clause for show_offline even if there is some redundant code here because this isn't LISP but C ;) */ +	if( set_getbool( &ic->irc->set, "show_offline" ) && set_getbool( &ic->irc->set, "away_devoice" ) )  	{  		char *from; @@ -714,9 +738,43 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags,  			from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick,  			                                    ic->irc->myhost );  		} -		irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel, -		                                          u->away?'-':'+', u->nick ); -		g_free( from ); + +		/* if we use show_offline, we op online users, voice away users, and devoice/deop offline users */ +		if( flags & OPT_LOGGED_IN ) +		{ +			/* user is "online" (either really online or away) */ +			irc_write( ic->irc, ":%s MODE %s %cv%co %s %s", from, ic->irc->channel, +			                                          u->away?'+':'-', u->away?'-':'+', u->nick, u->nick ); +		} +		else +		{ +			/* user is offline */ +			irc_write( ic->irc, ":%s MODE %s -vo %s %s", from, ic->irc->channel, u->nick, u->nick ); +		} +	} +	else +	{  +		/* LISPy... */ +		if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */ +		    ( u->online ) &&						/* Don't touch offline people */ +		    ( ( ( u->online != oo ) && !u->away ) ||			/* Voice joining people */ +		      ( ( u->online == oo ) && ( oa == !u->away ) ) ) )		/* (De)voice people changing state */ +		{ +			char *from; + +			if( set_getbool( &ic->irc->set, "simulate_netsplit" ) ) +			{ +				from = g_strdup( ic->irc->myhost ); +			} +			else +			{ +				from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick, +				                                    ic->irc->myhost ); +			} +			irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel, +			                                          u->away?'-':'+', u->nick ); +			g_free( from ); +		}  	}  } @@ -1193,7 +1251,7 @@ static char *format_timestamp( irc_t *irc, time_t msg_ts )  	else  		return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d "  		                        "%02d:%02d:%02d\x02]\x02 ", -		                        msg.tm_year + 1900, msg.tm_mon, msg.tm_mday, +		                        msg.tm_year + 1900, msg.tm_mon + 1, msg.tm_mday,  		                        msg.tm_hour, msg.tm_min, msg.tm_sec );  } diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index 589f2088..9c7b060c 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -65,7 +65,7 @@ static void twitter_main_loop_start( struct im_connection *ic )  } -static struct oauth_service twitter_oauth = +static const struct oauth_service twitter_oauth =  {  	"http://api.twitter.com/oauth/request_token",  	"http://api.twitter.com/oauth/access_token", @@ -114,7 +114,7 @@ static gboolean twitter_oauth_callback( struct oauth_info *info )  	}  	else if( info->stage == OAUTH_ACCESS_TOKEN )  	{ -		if( info->token == NULL ) +		if( info->token == NULL || info->token_secret == NULL )  		{  			imcb_error( ic, "OAuth error: %s", info->http->status_string );  			imc_logout( ic, TRUE ); | 
