From 280e655722c8660ec2dff9b08f82b10d5559bfd9 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 6 Aug 2008 00:07:07 +0100 Subject: Simple exponential backoff code. Have to add a maximum delay setting, something like 5*5<300: 5s, multiply by 5 on each failure, but stop increasing once we hit 5m. --- account.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'account.c') diff --git a/account.c b/account.c index 2c6e1069..cfe04c40 100644 --- a/account.c +++ b/account.c @@ -233,3 +233,39 @@ void account_off( irc_t *irc, account_t *a ) cancel_auto_reconnect( a ); } } + +char *set_eval_account_reconnect_delay( set_t *set, char *value ) +{ + int start; + char op; + int step; + + if( sscanf( value, "%d%c%d", &start, &op, &step ) == 3 && + step > 0 && ( op == '+' || op == '*' ) ) + return value; + 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; +} -- cgit v1.2.3 From 4230221725b0cd0f6a9b84f726759d20ff9f0e62 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 10 Aug 2008 00:00:38 +0100 Subject: Added ceiling to auto-reconnect delay, changed the default to 5*3<900 and added documentation. --- account.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 17 deletions(-) (limited to 'account.c') 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; } -- cgit v1.2.3 From 3b32017ca4d13d1385c8c96eef14fcd62ba17464 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 19 Aug 2008 23:21:07 +0100 Subject: Better handling of NULLs passed to set_eval_account(). Still confusing though, set_reset() is broken for variables that can actually be NULL. --- account.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'account.c') diff --git a/account.c b/account.c index 07df69e4..c7480996 100644 --- a/account.c +++ b/account.c @@ -78,22 +78,10 @@ char *set_eval_account( set_t *set, char *value ) if( set->flags & ACC_SET_OFFLINE_ONLY && acc->ic ) return NULL; - if( strcmp( set->key, "username" ) == 0 ) - { - g_free( acc->user ); - acc->user = g_strdup( value ); - return value; - } - else if( strcmp( set->key, "password" ) == 0 ) - { - g_free( acc->pass ); - acc->pass = g_strdup( value ); - return NULL; /* password shouldn't be visible in plaintext! */ - } - else if( strcmp( set->key, "server" ) == 0 ) + if( strcmp( set->key, "server" ) == 0 ) { g_free( acc->server ); - if( *value ) + if( value && *value ) { acc->server = g_strdup( value ); return value; @@ -104,6 +92,22 @@ char *set_eval_account( set_t *set, char *value ) return g_strdup( set->def ); } } + else if( value == NULL ) + { + /* Noop, the other three can't be NULL. */ + } + else if( strcmp( set->key, "username" ) == 0 ) + { + g_free( acc->user ); + acc->user = g_strdup( value ); + return value; + } + else if( strcmp( set->key, "password" ) == 0 ) + { + g_free( acc->pass ); + acc->pass = g_strdup( value ); + return NULL; /* password shouldn't be visible in plaintext! */ + } else if( strcmp( set->key, "auto_connect" ) == 0 ) { if( !is_bool( value ) ) -- cgit v1.2.3 From 7125cb3775a0e384c0f2fc08fd56df9582199502 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 24 Aug 2008 19:01:05 +0100 Subject: Added SET_INVALID, which set evaluators should now return instead of NULL when the given value is not accepted. This to allow certain variables actually be set to NULL (server, for example). This should fully close #444. --- account.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'account.c') diff --git a/account.c b/account.c index c7480996..d6b219a9 100644 --- a/account.c +++ b/account.c @@ -76,7 +76,7 @@ char *set_eval_account( set_t *set, char *value ) /* Double-check: We refuse to edit on-line accounts. */ if( set->flags & ACC_SET_OFFLINE_ONLY && acc->ic ) - return NULL; + return SET_INVALID; if( strcmp( set->key, "server" ) == 0 ) { @@ -88,14 +88,10 @@ char *set_eval_account( set_t *set, char *value ) } else { - acc->server = NULL; + acc->server = g_strdup( set->def ); return g_strdup( set->def ); } } - else if( value == NULL ) - { - /* Noop, the other three can't be NULL. */ - } else if( strcmp( set->key, "username" ) == 0 ) { g_free( acc->user ); @@ -104,20 +100,29 @@ char *set_eval_account( set_t *set, char *value ) } else if( strcmp( set->key, "password" ) == 0 ) { - g_free( acc->pass ); - acc->pass = g_strdup( value ); - return NULL; /* password shouldn't be visible in plaintext! */ + if( value ) + { + g_free( acc->pass ); + acc->pass = g_strdup( value ); + return NULL; /* password shouldn't be visible in plaintext! */ + } + else + { + /* NULL can (should) be stored in the set_t + variable, but is otherwise not correct. */ + return SET_INVALID; + } } else if( strcmp( set->key, "auto_connect" ) == 0 ) { if( !is_bool( value ) ) - return NULL; + return SET_INVALID; acc->auto_connect = bool2int( value ); return value; } - return NULL; + return SET_INVALID; } account_t *account_get( irc_t *irc, char *id ) @@ -257,7 +262,7 @@ int account_reconnect_delay_parse( char *value, struct account_reconnect_delay * 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. */ + dead simple and I immediately know where to continue parsing. */ if( *value == 0 ) /* If the string ends now, the delay is constant. */ @@ -290,7 +295,7 @@ 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; + return account_reconnect_delay_parse( value, &p ) ? value : SET_INVALID; } int account_reconnect_delay( account_t *a ) -- cgit v1.2.3 From f3579fd061746fe88c53330a2b9002da4193b37a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 24 Aug 2008 21:52:31 +0100 Subject: Clearer feedback after set/account set commands. --- account.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'account.c') diff --git a/account.c b/account.c index d6b219a9..f3e15d7e 100644 --- a/account.c +++ b/account.c @@ -54,7 +54,7 @@ account_t *account_add( irc_t *irc, struct prpl *prpl, char *user, char *pass ) s = set_add( &a->set, "auto_reconnect", "true", set_eval_bool, a ); s = set_add( &a->set, "password", NULL, set_eval_account, a ); - s->flags |= ACC_SET_NOSAVE; + s->flags |= ACC_SET_NOSAVE | SET_NULL_OK; s = set_add( &a->set, "username", NULL, set_eval_account, a ); s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; -- cgit v1.2.3 From d995c9b5de1bff5e3eb5de47b7ffbd3e92e2ac3d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 31 Aug 2008 15:54:39 +0100 Subject: Added cleanup code. --- account.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'account.c') diff --git a/account.c b/account.c index f3e15d7e..f547d8f1 100644 --- a/account.c +++ b/account.c @@ -189,6 +189,7 @@ account_t *account_get( irc_t *irc, char *id ) void account_del( irc_t *irc, account_t *acc ) { account_t *a, *l = NULL; + struct chat *c, *nc; if( acc->ic ) /* Caller should have checked, accounts still in use can't be deleted. */ @@ -202,6 +203,13 @@ void account_del( irc_t *irc, account_t *acc ) else irc->accounts = a->next; + for( c = irc->chatrooms; c; c = nc ) + if( acc == c->acc ) + { + nc = c->next; + chat_del( irc, c ); + } + while( a->set ) set_del( &a->set, a->set->key ); -- cgit v1.2.3 From f86a3d558e1e69a3728c8f8fd014cbcd6271f98e Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 1 Sep 2008 11:21:01 +0100 Subject: Fixed ugly looping bug in chatroom list cleanup code. --- account.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'account.c') diff --git a/account.c b/account.c index f547d8f1..cb54731f 100644 --- a/account.c +++ b/account.c @@ -204,11 +204,11 @@ void account_del( irc_t *irc, account_t *acc ) irc->accounts = a->next; for( c = irc->chatrooms; c; c = nc ) + { + nc = c->next; if( acc == c->acc ) - { - nc = c->next; chat_del( irc, c ); - } + } while( a->set ) set_del( &a->set, a->set->key ); -- cgit v1.2.3