aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--account.c78
-rw-r--r--doc/user-guide/commands.xml10
-rw-r--r--irc.c2
-rw-r--r--protocols/nogaim.c6
4 files changed, 72 insertions, 24 deletions
diff --git a/account.c b/account.c
index cfe04c40..07df69e4 100644
--- a/account.c
+++ b/account.c
@@ -234,38 +234,82 @@ void account_off( irc_t *irc, account_t *a )
}
}
-char *set_eval_account_reconnect_delay( set_t *set, char *value )
+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;
- if( sscanf( value, "%d%c%d", &start, &op, &step ) == 3 &&
- step > 0 && ( op == '+' || op == '*' ) )
- return value;
- else
- return set_eval_int( set, value );
+ /* 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" );
- int start, step;
- char op;
+ struct account_reconnect_delay p;
- if( sscanf( setting, "%d%c%d", &start, &op, &step ) == 3 && step > 0 )
+ if( account_reconnect_delay_parse( setting, &p ) )
{
if( a->auto_reconnect_delay == 0 )
- return a->auto_reconnect_delay = start;
- else if( op == '+' )
- return a->auto_reconnect_delay += step;
- else if( op == '*' )
- return a->auto_reconnect_delay *= step;
+ 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 if( sscanf( setting, "%d", &start ) == 1 )
+ else
{
- return a->auto_reconnect_delay = start;
+ a->auto_reconnect_delay = 0;
}
- return 0;
+ return a->auto_reconnect_delay;
}
diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml
index 6d77f8cd..cd16808e 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&lt;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 &quot;10*10&quot;, 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 &lt; you can give a maximum delay.
</para>
<para>
diff --git a/irc.c b/irc.c
index 3fe80a4b..30956bc2 100644
--- a/irc.c
+++ b/irc.c
@@ -138,7 +138,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_account_reconnect_delay, 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/nogaim.c b/protocols/nogaim.c
index eb3fc2ad..b6f8d6e4 100644
--- a/protocols/nogaim.c
+++ b/protocols/nogaim.c
@@ -293,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. */
@@ -332,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 = account_reconnect_delay( a );
-
imcb_log( ic, "Reconnecting in %d seconds..", delay );
a->reconnect = b_timeout_add( delay * 1000, auto_reconnect, a );
}