diff options
-rw-r--r-- | account.c | 31 | ||||
-rw-r--r-- | account.h | 6 | ||||
-rw-r--r-- | irc.c | 46 | ||||
-rw-r--r-- | protocols/jabber/jabber.c | 2 | ||||
-rw-r--r-- | protocols/jabber/jabber_util.c | 4 | ||||
-rw-r--r-- | protocols/nogaim.c | 12 | ||||
-rw-r--r-- | root_commands.c | 4 | ||||
-rw-r--r-- | set.c | 22 | ||||
-rw-r--r-- | set.h | 8 |
9 files changed, 79 insertions, 56 deletions
@@ -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 ) @@ -55,8 +55,8 @@ 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 -#define ACC_SET_ONLINE_ONLY 4 +#define ACC_SET_NOSAVE 0x01 +#define ACC_SET_OFFLINE_ONLY 0x02 +#define ACC_SET_ONLINE_ONLY 0x04 #endif @@ -76,6 +76,7 @@ irc_t *irc_new( int fd ) irc_t *irc; struct sockaddr_storage sock; socklen_t socklen = sizeof( sock ); + set_t *s; irc = g_new0( irc_t, 1 ); @@ -135,28 +136,29 @@ irc_t *irc_new( int fd ) irc_connection_list = g_slist_append( irc_connection_list, irc ); - 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", "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 ); - set_add( &irc->set, "debug", "false", set_eval_bool, irc ); - set_add( &irc->set, "default_target", "root", NULL, irc ); - set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); - set_add( &irc->set, "handle_unknown", "root", NULL, irc ); - set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc ); - set_add( &irc->set, "ops", "both", set_eval_ops, irc ); - set_add( &irc->set, "password", NULL, passchange, irc ); - set_add( &irc->set, "private", "true", set_eval_bool, irc ); - set_add( &irc->set, "query_order", "lifo", NULL, irc ); - set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc ); - set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); - set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc ); - set_add( &irc->set, "strip_html", "true", NULL, irc ); - set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc ); - set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc ); + s = set_add( &irc->set, "away_devoice", "true", set_eval_away_devoice, irc ); + s = set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc ); + s = set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc ); + s = set_add( &irc->set, "auto_reconnect_delay", "5*3<900", set_eval_account_reconnect_delay, irc ); + s = set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); + s = set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); + s = set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); + s = set_add( &irc->set, "debug", "false", set_eval_bool, irc ); + s = set_add( &irc->set, "default_target", "root", NULL, irc ); + s = set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); + s = set_add( &irc->set, "handle_unknown", "root", NULL, irc ); + s = set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc ); + s = set_add( &irc->set, "ops", "both", set_eval_ops, irc ); + s = set_add( &irc->set, "password", NULL, passchange, irc ); + s->flags |= SET_NULL_OK; + s = set_add( &irc->set, "private", "true", set_eval_bool, irc ); + 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, "simulate_netsplit", "true", set_eval_bool, irc ); + s = set_add( &irc->set, "strip_html", "true", NULL, irc ); + s = set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc ); + s = set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc ); conf_loaddefaults( irc ); diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index c9c1d0a0..ac8638cf 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -69,7 +69,7 @@ static void jabber_init( account_t *acc ) s = set_add( &acc->set, "resource_select", "priority", NULL, acc ); s = set_add( &acc->set, "server", NULL, set_eval_account, acc ); - s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; + s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY | SET_NULL_OK; s = set_add( &acc->set, "ssl", "false", set_eval_bool, acc ); s->flags |= ACC_SET_OFFLINE_ONLY; diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c index 1bee5009..19a73b6a 100644 --- a/protocols/jabber/jabber_util.c +++ b/protocols/jabber/jabber_util.c @@ -36,10 +36,10 @@ char *set_eval_priority( set_t *set, char *value ) { /* Priority is a signed 8-bit integer, according to RFC 3921. */ if( i < -128 || i > 127 ) - return NULL; + return SET_INVALID; } else - return NULL; + return SET_INVALID; /* Only run this stuff if the account is online ATM, and if the setting seems to be acceptable. */ diff --git a/protocols/nogaim.c b/protocols/nogaim.c index b6f8d6e4..6a267adf 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -927,14 +927,10 @@ char *set_eval_away_devoice( set_t *set, char *value ) irc_t *irc = set->data; int st; - if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) - st = 1; - else if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) ) - st = 0; - else if( sscanf( value, "%d", &st ) != 1 ) - return( NULL ); + if( !is_bool( value ) ) + return SET_INVALID; - st = st != 0; + st = bool2int( value ); /* Horror.... */ @@ -978,7 +974,7 @@ char *set_eval_away_devoice( set_t *set, char *value ) irc->channel, pm, v, list ); } - return( set_eval_bool( set, value ) ); + return value; } diff --git a/root_commands.c b/root_commands.c index f55c4b5e..56a405a3 100644 --- a/root_commands.c +++ b/root_commands.c @@ -609,6 +609,8 @@ static void cmd_rename( irc_t *irc, char **cmd ) g_free( irc->mynick ); irc->mynick = g_strdup( cmd[2] ); + /* If we're called internally (user did "set root_nick"), + let's not go O(INF). :-) */ if( strcmp( cmd[0], "set_rename" ) != 0 ) set_setstr( &irc->set, "root_nick", cmd[2] ); } @@ -632,7 +634,7 @@ char *set_eval_root_nick( set_t *set, char *new_nick ) cmd_rename( irc, cmd ); } - return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : NULL; + return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : SET_INVALID; } static void cmd_remove( irc_t *irc, char **cmd ) @@ -25,6 +25,9 @@ #define BITLBEE_CORE #include "bitlbee.h" +/* Used to use NULL for this, but NULL is actually a "valid" value. */ +char *SET_INVALID = "nee"; + set_t *set_add( set_t **head, char *key, char *def, set_eval eval, void *data ) { set_t *s = set_find( head, key ); @@ -113,9 +116,20 @@ int set_setstr( set_t **head, char *key, char *value ) char *nv = value; if( !s ) + /* + Used to do this, but it never really made sense. s = set_add( head, key, NULL, NULL, NULL ); + */ + return 0; - if( s->eval && !( nv = s->eval( s, value ) ) ) + if( value == NULL && ( s->flags & SET_NULL_OK ) == 0 ) + return 0; + + /* Call the evaluator. For invalid values, evaluators should now + return SET_INVALID, but previously this was NULL. Try to handle + that too if NULL is not an allowed value for this setting. */ + if( s->eval && ( ( nv = s->eval( s, value ) ) == SET_INVALID || + ( ( s->flags & SET_NULL_OK ) == 0 && nv == NULL ) ) ) return 0; if( s->value ) @@ -186,14 +200,14 @@ char *set_eval_int( set_t *set, char *value ) for( ; *s; s ++ ) if( !isdigit( *s ) ) - return NULL; + return SET_INVALID; return value; } char *set_eval_bool( set_t *set, char *value ) { - return is_bool( value ) ? value : NULL; + return is_bool( value ) ? value : SET_INVALID; } char *set_eval_to_char( set_t *set, char *value ) @@ -225,7 +239,7 @@ char *set_eval_ops( set_t *set, char *value ) irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost, irc->channel, "-oo", irc->nick, irc->mynick ); else - return NULL; + return SET_INVALID; return value; } @@ -43,6 +43,10 @@ struct set; typedef char *(*set_eval) ( struct set *set, char *value ); +extern char *SET_INVALID; + +#define SET_NULL_OK 0x0100 + typedef struct set { void *data; /* Here you can save a pointer to the @@ -60,8 +64,8 @@ typedef struct set int flags; /* See account.h, for example. set.c doesn't use this (yet?). */ - /* Eval: Returns NULL if the value is incorrect or exactly the - passed value variable. When returning a corrected value, + /* Eval: Returns SET_INVALID if the value is incorrect or exactly + the passed value variable. When returning a corrected value, set_setstr() should be able to free() the returned string! */ set_eval eval; struct set *next; |