Index: account.c
===================================================================
--- account.c	(revision 280e655722c8660ec2dff9b08f82b10d5559bfd9)
+++ account.c	(revision 4230221725b0cd0f6a9b84f726759d20ff9f0e62)
@@ -235,37 +235,81 @@
 }
 
-char *set_eval_account_reconnect_delay( set_t *set, char *value )
+struct account_reconnect_delay
 {
 	int start;
 	char op;
 	int step;
-	
-	if( sscanf( value, "%d%c%d", &start, &op, &step ) == 3 &&
-	    step > 0 && ( op == '+' || op == '*' ) )
-		return value;
+	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
-		return set_eval_int( set, value );
-}
-
-int account_reconnect_delay( account_t *a )
-{
-	char *setting = set_getstr( &a->irc->set, "auto_reconnect_delay" );
-	int start, step;
-	char op;
-	
-	if( sscanf( setting, "%d%c%d", &start, &op, &step ) == 3 && step > 0 )
-	{
-		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;
-	}
-	else if( sscanf( setting, "%d", &start ) == 1 )
-	{
-		return a->auto_reconnect_delay = start;
-	}
-	
-	return 0;
-}
+	{
+		a->auto_reconnect_delay = 0;
+	}
+	
+	return a->auto_reconnect_delay;
+}
Index: doc/user-guide/commands.xml
===================================================================
--- doc/user-guide/commands.xml	(revision 280e655722c8660ec2dff9b08f82b10d5559bfd9)
+++ doc/user-guide/commands.xml	(revision 4230221725b0cd0f6a9b84f726759d20ff9f0e62)
@@ -321,10 +321,14 @@
 	</bitlbee-setting>
 
-	<bitlbee-setting name="auto_reconnect_delay" type="integer" scope="global">
-		<default>300</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.
+	<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 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>
 
Index: irc.c
===================================================================
--- irc.c	(revision 280e655722c8660ec2dff9b08f82b10d5559bfd9)
+++ irc.c	(revision 4230221725b0cd0f6a9b84f726759d20ff9f0e62)
@@ -139,5 +139,5 @@
 	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 );
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision 280e655722c8660ec2dff9b08f82b10d5559bfd9)
+++ protocols/nogaim.c	(revision 4230221725b0cd0f6a9b84f726759d20ff9f0e62)
@@ -294,4 +294,5 @@
 	user_t *t, *u;
 	account_t *a;
+	int delay;
 	
 	/* Nested calls might happen sometimes, this is probably the best
@@ -333,8 +334,7 @@
 	}
 	else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) &&
-	         set_getbool( &a->set, "auto_reconnect" ) )
-	{
-		int delay = account_reconnect_delay( a );
-		
+	         set_getbool( &a->set, "auto_reconnect" ) &&
+	         ( delay = account_reconnect_delay( a ) ) > 0 )
+	{
 		imcb_log( ic, "Reconnecting in %d seconds..", delay );
 		a->reconnect = b_timeout_add( delay * 1000, auto_reconnect, a );
