diff options
| author | ulim <a.sporto+bee@gmail.com> | 2008-08-10 12:42:52 +0200 | 
|---|---|---|
| committer | ulim <a.sporto+bee@gmail.com> | 2008-08-10 12:42:52 +0200 | 
| commit | 87f525e0469f80aea715692ea74ebccbe688ae45 (patch) | |
| tree | 395bda41309884b9119c358f8c48f5a8163c2594 | |
| parent | 8661caad555f4306cf36ee37979a7637b05d5cd4 (diff) | |
| parent | a8305126a38eb977c51046dd4ec3ac258a20a98f (diff) | |
Merged in upstream r416 which includes my msn_write_msg patch. w00t! ;)
| -rw-r--r-- | account.c | 80 | ||||
| -rw-r--r-- | account.h | 3 | ||||
| -rw-r--r-- | conf.c | 9 | ||||
| -rw-r--r-- | doc/user-guide/commands.xml | 10 | ||||
| -rw-r--r-- | irc.c | 2 | ||||
| -rw-r--r-- | protocols/msn/msn.c | 61 | ||||
| -rw-r--r-- | protocols/msn/msn.h | 6 | ||||
| -rw-r--r-- | protocols/msn/sb.c | 42 | ||||
| -rw-r--r-- | protocols/nogaim.c | 10 | 
9 files changed, 157 insertions, 66 deletions
| @@ -233,3 +233,83 @@ void account_off( irc_t *irc, account_t *a )  		cancel_auto_reconnect( a );  	}  } + +struct account_reconnect_delay +{ +	int start; +	char op; +	int step; +	int max; +}; + +int account_reconnect_delay_parse( char *value, struct account_reconnect_delay *p ) +{ +	memset( p, 0, sizeof( *p ) ); +	/* A whole day seems like a sane "maximum maximum". */ +	p->max = 86400; +	 +	/* Format: /[0-9]+([*+][0-9]+(<[0-9+]))/ */ +	while( *value && isdigit( *value ) ) +		p->start = p->start * 10 + *value++ - '0'; +	 +	/* Sure, call me evil for implementing my own fscanf here, but it's +	   dead simple and I'm immediately at the next part to parse. */ +	 +	if( *value == 0 ) +		/* If the string ends now, the delay is constant. */ +		return 1; +	else if( *value != '+' && *value != '*' ) +		/* Otherwise allow either a + or a * */ +		return 0; +	 +	p->op = *value++; +	 +	/* + or * the delay by this number every time. */ +	while( *value && isdigit( *value ) ) +		p->step = p->step * 10 + *value++ - '0'; +	 +	if( *value == 0 ) +		/* Use the default maximum (one day). */ +		return 1; +	else if( *value != '<' ) +		return 0; +	 +	p->max = 0; +	value ++; +	while( *value && isdigit( *value ) ) +		p->max = p->max * 10 + *value++ - '0'; +	 +	return p->max > 0; +} + +char *set_eval_account_reconnect_delay( set_t *set, char *value ) +{ +	struct account_reconnect_delay p; +	 +	return account_reconnect_delay_parse( value, &p ) ? value : NULL; +} + +int account_reconnect_delay( account_t *a ) +{ +	char *setting = set_getstr( &a->irc->set, "auto_reconnect_delay" ); +	struct account_reconnect_delay p; +	 +	if( account_reconnect_delay_parse( setting, &p ) ) +	{ +		if( a->auto_reconnect_delay == 0 ) +			a->auto_reconnect_delay = p.start; +		else if( p.op == '+' ) +			a->auto_reconnect_delay += p.step; +		else if( p.op == '*' ) +			a->auto_reconnect_delay *= p.step; +		 +		if( a->auto_reconnect_delay > p.max ) +			a->auto_reconnect_delay = p.max; +	} +	else +	{ +		a->auto_reconnect_delay = 0; +	} +	 +	return a->auto_reconnect_delay; +} @@ -34,6 +34,7 @@ typedef struct account  	char *server;  	int auto_connect; +	int auto_reconnect_delay;  	int reconnect;  	set_t *set; @@ -51,6 +52,8 @@ void account_on( irc_t *irc, account_t *a );  void account_off( irc_t *irc, account_t *a );  char *set_eval_account( set_t *set, char *value ); +char *set_eval_account_reconnect_delay( set_t *set, char *value ); +int account_reconnect_delay( account_t *a );  #define ACC_SET_NOSAVE		1  #define ACC_SET_OFFLINE_ONLY	2 @@ -78,7 +78,7 @@ conf_t *conf_load( int argc, char *argv[] )  		   at a *valid* configuration file. */  	} -	while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hu:" ) ) >= 0 ) +	while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )  	/*     ^^^^ Just to make sure we skip this step from the REHASH handler. */  	{  		if( opt == 'i' ) @@ -146,6 +146,13 @@ conf_t *conf_load( int argc, char *argv[] )  			        "  -h  Show this help page.\n" );  			return NULL;  		} +		else if( opt == 'R' ) +		{ +			/* Backward compatibility; older BitlBees passed this +			   info using a command-line flag. Allow people to +			   upgrade from such a version for now. */ +			setenv( "_BITLBEE_RESTART_STATE", optarg, 0 ); +		}  		else if( opt == 'u' )  		{  			g_free( conf->user ); diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml index 7081663f..f22f6177 100644 --- a/doc/user-guide/commands.xml +++ b/doc/user-guide/commands.xml @@ -320,12 +320,16 @@  		</description>  	</bitlbee-setting> -	<bitlbee-setting name="auto_reconnect_delay" type="integer" scope="global"> -		<default>300</default> +	<bitlbee-setting name="auto_reconnect_delay" type="string" scope="global"> +		<default>5*3<900</default>  		<description>  			<para> -				Tell BitlBee after how many seconds it should attempt to bring an IM-connection back up after a crash. It's not a good idea to set this value very low, it will cause too much useless traffic when an IM-server is down for a few hours. +				Tell BitlBee after how many seconds it should attempt to bring a broken IM-connection back up. +			</para> + +			<para> +				This can be one integer, for a constant delay. One can also set it to something like "10*10", which means wait for ten seconds on the first reconnect, multiply it by ten on every failure. Once successfully connected, this delay is re-set to the initial value. With < you can give a maximum delay.  			</para>  			<para> @@ -139,7 +139,7 @@ irc_t *irc_new( int fd )  	set_add( &irc->set, "away_devoice", "true",  set_eval_away_devoice, irc );  	set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc );  	set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc ); -	set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_int, irc ); +	set_add( &irc->set, "auto_reconnect_delay", "5*3<900", set_eval_account_reconnect_delay, irc );  	set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc );  	set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc );  	set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index a2e8519a..046b2772 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -112,7 +112,6 @@ static void msn_logout( struct im_connection *ic )  static int msn_buddy_msg( struct im_connection *ic, char *who, char *message, int away )  {  	struct msn_switchboard *sb; -	struct msn_data *md = ic->proto_data;  	if( ( sb = msn_sb_by_handle( ic, who ) ) )  	{ @@ -121,47 +120,13 @@ static int msn_buddy_msg( struct im_connection *ic, char *who, char *message, in  	else  	{  		struct msn_message *m; -		char buf[1024];  		/* Create a message. We have to arrange a usable switchboard, and send the message later. */  		m = g_new0( struct msn_message, 1 );  		m->who = g_strdup( who );  		m->text = g_strdup( message ); -		/* FIXME: *CHECK* the reliability of using spare sb's! */ -		if( ( sb = msn_sb_spare( ic ) ) ) -		{ -			debug( "Trying to use a spare switchboard to message %s", who ); -			 -			sb->who = g_strdup( who ); -			g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, who ); -			if( msn_sb_write( sb, buf, strlen( buf ) ) ) -			{ -				/* He/She should join the switchboard soon, let's queue the message. */ -				sb->msgq = g_slist_append( sb->msgq, m ); -				return( 1 ); -			} -		} -		 -		debug( "Creating a new switchboard to message %s", who ); -		 -		/* If we reach this line, there was no spare switchboard, so let's make one. */ -		g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); -		if( !msn_write( ic, buf, strlen( buf ) ) ) -		{ -			g_free( m->who ); -			g_free( m->text ); -			g_free( m ); -			 -			return( 0 ); -		} -		 -		/* And queue the message to md. We'll pick it up when the switchboard comes up. */ -		md->msgq = g_slist_append( md->msgq, m ); -		 -		/* FIXME: If the switchboard creation fails, the message will not be sent. */ -		 -		return( 1 ); +		return msn_sb_write_msg( ic, m );  	}  	return( 0 ); @@ -251,8 +216,6 @@ static void msn_chat_leave( struct groupchat *c )  static struct groupchat *msn_chat_with( struct im_connection *ic, char *who )  {  	struct msn_switchboard *sb; -	struct msn_data *md = ic->proto_data; -	char buf[1024];  	if( ( sb = msn_sb_by_handle( ic, who ) ) )  	{ @@ -263,31 +226,13 @@ static struct groupchat *msn_chat_with( struct im_connection *ic, char *who )  	{  		struct msn_message *m; -		if( ( sb = msn_sb_spare( ic ) ) ) -		{ -			debug( "Trying to reuse an existing switchboard as a groupchat with %s", who ); -			g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, who ); -			if( msn_sb_write( sb, buf, strlen( buf ) ) ) -				return msn_sb_to_chat( sb ); -		} -		 -		/* If the stuff above failed for some reason: */ -		debug( "Creating a new switchboard to groupchat with %s", who ); -		 -		/* Request a new switchboard. */ -		g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); -		if( !msn_write( ic, buf, strlen( buf ) ) ) -			return( 0 ); -		  		/* Create a magic message. This is quite hackish, but who cares? :-P */  		m = g_new0( struct msn_message, 1 );  		m->who = g_strdup( who );  		m->text = g_strdup( GROUPCHAT_SWITCHBOARD_MESSAGE ); -		/* Queue the magic message and cross your fingers. */ -		md->msgq = g_slist_append( md->msgq, m ); -		 -		/* FIXME: Can I try to return something here already? */ +		msn_sb_write_msg( ic, m ); +  		return NULL;  	} diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 63759303..7c849acf 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -23,6 +23,9 @@    Suite 330, Boston, MA  02111-1307  USA  */ +#ifndef _MSN_H +#define _MSN_H +  /* Some hackish magicstrings to make special-purpose messages/switchboards.   */  #define TYPING_NOTIFICATION_MESSAGE "\r\r\rBEWARE, ME R TYPINK MESSAGE!!!!\r\r\r" @@ -175,3 +178,6 @@ int msn_sb_sendmessage( struct msn_switchboard *sb, char *text );  struct groupchat *msn_sb_to_chat( struct msn_switchboard *sb );  void msn_sb_destroy( struct msn_switchboard *sb );  gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond ); +int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ); + +#endif //_MSN_H diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index 18c41ef5..e9526234 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -47,6 +47,48 @@ int msn_sb_write( struct msn_switchboard *sb, char *s, int len )  	return( 1 );  } +int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ) +{ +	struct msn_data *md = ic->proto_data; +	struct msn_switchboard *sb; +	char buf[1024]; + +	/* FIXME: *CHECK* the reliability of using spare sb's! */ +	if( ( sb = msn_sb_spare( ic ) ) ) +	{ +		debug( "Trying to use a spare switchboard to message %s", m->who ); +		 +		sb->who = g_strdup( m->who ); +		g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, m->who ); +		if( msn_sb_write( sb, buf, strlen( buf ) ) ) +		{ +			/* He/She should join the switchboard soon, let's queue the message. */ +			sb->msgq = g_slist_append( sb->msgq, m ); +			return( 1 ); +		} +	} +	 +	debug( "Creating a new switchboard to message %s", m->who ); +	 +	/* If we reach this line, there was no spare switchboard, so let's make one. */ +	g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); +	if( !msn_write( ic, buf, strlen( buf ) ) ) +	{ +		g_free( m->who ); +		g_free( m->text ); +		g_free( m ); +		 +		return( 0 ); +	} +	 +	/* And queue the message to md. We'll pick it up when the switchboard comes up. */ +	md->msgq = g_slist_append( md->msgq, m ); +	 +	/* FIXME: If the switchboard creation fails, the message will not be sent. */ +	 +	return( 1 ); +} +  struct msn_switchboard *msn_sb_create( struct im_connection *ic, char *host, int port, char *key, int session )  {  	struct msn_data *md = ic->proto_data; diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 7466e93a..b6f8d6e4 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -266,6 +266,10 @@ void imcb_connected( struct im_connection *ic )  	/* Also necessary when we're not away, at least for some of the  	   protocols. */  	imc_set_away( ic, u->away ); +	 +	/* Apparently we're connected successfully, so reset the +	   exponential backoff timer. */ +	ic->acc->auto_reconnect_delay = 0;  }  gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond ) @@ -289,6 +293,7 @@ void imc_logout( struct im_connection *ic, int allow_reconnect )  	irc_t *irc = ic->irc;  	user_t *t, *u;  	account_t *a; +	int delay;  	/* Nested calls might happen sometimes, this is probably the best  	   place to catch them. */ @@ -328,10 +333,9 @@ void imc_logout( struct im_connection *ic, int allow_reconnect )  		/* Uhm... This is very sick. */  	}  	else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) && -	         set_getbool( &a->set, "auto_reconnect" ) ) +	         set_getbool( &a->set, "auto_reconnect" ) && +	         ( delay = account_reconnect_delay( a ) ) > 0 )  	{ -		int delay = set_getint( &irc->set, "auto_reconnect_delay" ); -		  		imcb_log( ic, "Reconnecting in %d seconds..", delay );  		a->reconnect = b_timeout_add( delay * 1000, auto_reconnect, a );  	} | 
