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; | 
